Mutate to use preferred operators while routing
Operators are different. Think about payment methods, locations, charger experience. To take care of this, operators can be ranked and excluded. Either in the dashboard or in the API. In this example, the API approach will be demonstrated.
View on Github
Requirements
- Chargetrip API key - to plot routes outside this region
- Mapbox API key - to display the map
- URQL - a lightweight graphQL client
Steps to take
- Plotting a route with preferred operators starts by executing the
newRoute
mutation. This mutation requires information about the car, origin and destination. To use preferred operators theoperators
argument needs to be configured. Thetype
needs to be set as well as theranking
orexcluding
. After the mutation is finished executing a routeid
will be returned. - This
id
can be used to request route updates through therouteUpdatedById
subscription. This subscription receives dynamic updates. - After the subscription returns
done
as status, a route with preferred operators will be returned. If there are no operator preferred stations available it will fallback on stations from other operators. If all stations on a segment areexcluded
a route can fail to compute. Thepolyline
andlegs
object can be used to display the route and charge stations on the map. Additional data such as distance, duration and consumption are also available.
Next steps
To take routes a step further, elevation plots and dynamic variables will be introduced. Let's head over to that.
- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
import { createClient, createRequest, defaultExchanges, subscriptionExchange } from '@urql/core';
import { pipe, subscribe } from 'wonka';
import { SubscriptionClient } from 'subscriptions-transport-ws';
import { searchOperatorListQuery, createRouteQuery, routeUpdateSubscription } from './queries.js';
/**
* For the purpose of this example we use urql - lightweights GraphQL client.
* To establish a connection with Chargetrip GraphQL API you need to have an API key.
* The key in this example is a public one and gives an access only to a part of our extensive database.
* You need a registered `x-client-id` to access the full database.
* Read more about an authorisation in our documentation (https://docs.chargetrip.com/#authorisation).
*/
const headers = {
//Replace this x-client-id and app-id with your own to get access to more cars
'x-client-id': '5ed1175bad06853b3aa1e492',
'x-app-id': '623998b2c35130073829b2d2',
};
const subscriptionClient = new SubscriptionClient('wss://api.chargetrip.io/graphql', {
reconnect: true,
connectionParams: headers,
});
const client = createClient({
url: 'https://api.chargetrip.io/graphql',
fetchOptions: {
method: 'POST',
headers,
},
exchanges: [
...defaultExchanges,
subscriptionExchange({
forwardSubscription(operation) {
return subscriptionClient.request(operation);
},
}),
],
});
/**
* Searches through our operator list with pagination and various arguments.
* @param { Object } - Object that manages the page, size and search to be send towards our request
* @param { number } page - Number of the page we are on
* @param { number } size - Number of operators that we should fetch in one request
* @param { string } search - The keywords that we should filter our operator list on
* @param { function } callback - As soon as our asynchronous call is finished we do a callback to update our UI.
*/
export const fetchOperatorList = ({ page, size = 10, search = '', countries = [] }, callback) => {
client
.query(searchOperatorListQuery, { page, size, search, countries })
.toPromise()
.then(response => {
callback(response.data.operatorList);
});
};
/**
* Creates a route based on operator preference
* @param { Object } - Object that manages the operator preference
* @param { string } type - The type of operator preference. Can be either none, preferred or required.
* @param { string } [level1] - The first level of operator preference. The higher the more preferred an operator is.
* @param { string } [level2] - The second level of operator preference.
* @param { string } [level3] - The third level of operator preference.
* @param { string } [excluded] - The excluded level of operator preference. These operators won't be used when calculating the route.
*/
export const createRoute = ({ type = 'none', level1 = [], level2 = [], level3 = [], exclude = [] }, callback) => {
client
.mutation(createRouteQuery, { type, level1, level2, level3, exclude })
.toPromise()
.then(response => {
const routeId = response.data.newRoute;
if (!routeId) return Promise.reject('Could not retrieve Route ID. The response is not valid.');
const { unsubscribe } = pipe(
client.executeSubscription(createRequest(routeUpdateSubscription, { id: routeId })),
subscribe(result => {
const { status, route } = result.data.routeUpdatedById;
if (status === 'done' && route) {
unsubscribe();
callback(route);
} else if (status === 'not_found') {
callback();
}
}),
);
})
.catch(error => console.log(error));
};