Adding a new datasource - Visualisering/Visualisering GitHub Wiki

Your new service

The system uses services to handle local and external datasources. Each service is responsible for a single datasource and information from that single source.

The service should return a promise and, once the correct data has been collected, resolve with a object.

Consider a caching solution if the the same information is used frequently or in any other way needed. At the moment a simple caching solution could be to dump the object to a file, adding a timestamp to keep track of how stale the data is. Should a more advanced and performant solution be required raise the issue and it will be discussed.

Using your service

The next step is to actually use the service and the data it collects. For this purpose we use something that we call dataprocessors. Simply put they collect data using the services, process the data and combine it to something thats useful for the client.

The processor is expected to return a promise and once resolved to return a object with the relevant data.

Update the state

The system uses the Redux patten/library for handling data and state. So now that have some new data we need to update our state tree with this new information. This is done by dispatching an action to the datastore. The following code collects data from a processor and once the promise has been resolved dispatches the correct action.

myProcessor.getData()
           .then(processorData => store.dispatch(actions.myAction(processorData)));

For this to work we first need to write the action myAction. This is done in src/store/actions.js. Here we create a object with a string constant specifying which reducer and the data we want our reducer to operate on.

myAction(processorData) {
  return {type: "ADD_MY_DATA", processorData};
}

The next and final step is to add a new reducer. This is done in src/store/reducer.js. Since our data is immutable we never alter any data. We only create new objects. This is to eliminate unexpected behaviour and to keep a nice immutable oneway dataflow.

So using the same string constant we created in our action we add a new case where we will update the state tree by using Object.assign. Object.assign will combine currentState and our processorData to the new object and return this new state.

case "ADD_MY_DATA":
  return Object.assign( {}, currentState, { PART_OF_STATE_YOU_WANT_TO_UPDATE: action.processorData });

Now the new data has been added to the state tree.

Sending data to the client

Once the state tree has been updated a subscriber will be informed and the new state will be broadcast to all clients connected via websockets.

Your data is now on the client!

The client is also capable of requesting a subset of the state tree by sending an action via websockets. But that will be another howto.