Exploring Riot.js – Event-driven app (Step3)

August 31, 2015
Welcome to Step 3 of our "Exploring Riot.js - Part 3", humbly named:

Step #3 - an even even more amazing app than the even more amazing app (could it be?)


In the Step 2 of our “Exploring Riot.js – Part 3″, I’ve managed to sell you an amazing UX experience of the “Reload Stocks” button (maybe I should apply to our marketing office after all?). Yes, that was an awesome feature but unfortunately, by the time you’ve read the previous post, the feature was getting a bit old-fashioned… Why not go back to our roots? Going back to minimalist concepts? What if we were removing back the “Reload Stocks” button and at the same time we needn’t a F5 to refresh the browser? What if the table and the chart were refreshed every time the stocks change? In almost real-time…

riot.js stockmarket real-time application (step3) screenshot

 

Wait! Real-time you said? That reminds something… Yes! That’s it! An awesome technology that transforms a JSON API into a streaming API! And Stockmarket is a JSON API! It sounds like a job for Streamdata.io!

 

It's a job for streamdata.io!

 

Let’s start discovering how we can make our amazing app even more amazing (let’s say awesome!).

To better understand how to give a real-time flavor to our app, let's have an insight of our streamdata.io technology.
streamdata.io is a proxy that transforms a JSON API into a push API. Passing through streamdata.io offers several assets:

Here are some major features of streamdata.io. If you wish to get more information, I invite you to visit our website!

We have discussed the context. It's time to see how to achieve our goal: making our app amazingly reactive!

First, we need to add the streamdata.io Javascript SDK and a Javascript JSON-Patch library. Here I choose the fast-json-patch one. To install those two packages, run the following commands:

npm install streamdataio-js-sdk --save
npm install fast-json-patch --save



Now we need to import those two libraries in our index.html:
<script src="../node_modules/streamdataio-js-sdk/dist/streamdataio.min.js">></script>
<script src="../node_modules/fast-json-patch/dist/json-patch-duplex.min.js"></script>


Secondly, you need to get an appToken to be able to use streamdata.io. To do so, go to the streamdata.io portal, create an account and follow the instructions.  A few minutes later, you will become a lucky developer who owns the precious appToken!

As our Riot.js components are loosely-coupled thanks to the use of observables, there are no changes from this side. Furthemore, our architecture follows the Open-Close principle through the StockMarketService. So, the changes will only reside in this class.
'use strict';

class StockMarketService {
constructor(appToken, bus) {
var self = this;
var url = "http://stockmarket.streamdata.io/prices";

this.bus = bus;
var streamdata =
streamdataio.createEventSource(url, appToken, [], null);

self.data = [];

streamdata.onData(function(data) {
self.data = data;
self.bus.trigger('newStocksEvent', {stocks: self.data}, true);

}).onPatch(function(patches) {
jsonpatch.apply(self.data, patches);
self.bus.trigger('newStocksEvent', {stocks: self.data}, true);

}).onError(function(error) {
console.error(error);
self.bus.trigger('errorStocksEvent', error);
self.streamdata.close();

});

streamdata.open();
}
}

We pass the appToken to the constructor of the StockMarketService and create a streamdata object by calling streamdataio.createEventSource(.). Once this object is created, we can register to different callbacks. For us, the two most important callbacks to register are these passed to onData(.) and to onPatch(.):

Once the received data has been formatted, we send it through the bus.

Don't forget to call the open() function to effectively start the streaming session!

Note also that you don't need to use a solution for dealing with CORS on the Stockmarket API url anymore: streamdata.io handles it natively.

That's it for our StockMarketService.

Now, let's delete the stockmarket-button.tag and update the way we fetch the stocks from the Stockmarket API in the index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Hello World</title>

<link rel="stylesheet" type="text/css" href="node_modules/bootstrap/dist/css/bootstrap.min.css" />

<link rel="stylesheet" type="text/css" href="app/css/main.css" />
<link rel="stylesheet" type="text/css" href="app/css/stockmarket-barchart.css" />
</head>
<body>
<!-- mount point -->
<stockmarket-table></stockmarket-table>
<stockmarket-barchart height="500" width="960"></stockmarket-barchart>

<!-- include riot.js -->
<script src="../node_modules/riot/riot.min.js"></script>
<script src="../node_modules/d3/build/d3.min.js"></script>
<script src="../node_modules/fast-json-patch/dist/json-patch-duplex.min.js"></script>
<script src="../node_modules/streamdataio-js-sdk/dist/streamdataio.min.js"></script>
<script src="../app/js/stockmarket-service.js"></script>
<script src="../dist/js/stockmarket-table.js"></script>
<script src="../dist/js/stockmarket-barchart.js"></script>

<script>
var appToken = <YOUR STREAMDATAIO APP TOKEN>
var bus = riot.observable();
var stockMarketService = new StockMarketService(appToken, bus);
var areMounted = false;

bus.on('newStocksEvent', function (param) {
if (!areMounted) {
riot.mount('stockmarket-table', {title: 'Stocks', bus: bus, stocks: param.stocks});
riot.mount('stockmarket-barchart', {title: 'Graph', bus:bus, stocks: param.stocks});
areMounted = true;
}
});
</script>
</body>
</html>


That's all folks! With few changes, we now have a truly awesome app which UI updates in real-time! UX looks better than ever! ;)

Conclusion


The use of Riot.js observables helps to loosely-coupled our custom components. The Open-Close principle helps to minimize the code to change. Streamdata.io helps to bring a reactive UX to our demo. That rocks!

That rocks, no?

Oh, by the way, the code can be found on our GitHub (eventDrivenApp branch, tag step3).
 

Want more about riot.js?

Exploring Riot.js – Introduction

Exploring Riot.js – Get your hands dirty

Exploring Riot.js – Event-driven app (Step1)

Exploring Riot.js – Event-driven app (Step2)

Exploring Riot.js – Event-driven app (Step3) ... you are here!

Exploring Riot.js – En route to…

Exploring Riot.js – Route 66 (Takeaway)

There are 0 comments.

Have something to say?

Drop a comment below.

Share - 'Exploring Riot.js - Event-driven app (Step3)' on Google Share - 'Exploring Riot.js - Event-driven app (Step3)' on Facebook Share - 'Exploring Riot.js - Event-driven app (Step3)' on Twitter Share - 'Exploring Riot.js - Event-driven app (Step3)' on Reddit Share - 'Exploring Riot.js - Event-driven app (Step3)' on LinkedIn