simple online nosql database database with REST API and MongoDB queries
  • Features
  • Docs
  • Blog
  • Templates
  • Pricing
  • Contact
  • Sign Up
  • Log In

Blog

 The latest news and articles about restdb.io  

Database templates!
Don't forget to visit our template catalog! It's the fastest way to get up and running with a restdb.io database. View templates »

React in realtime

by Jon Erik Solheim
|
API|Tutorials|
  • Share on Facebook
  • Tweet
  • Add to Pocket
  • Share on LinkedIn
  • Send email

spash

Single page applications frameworks (SPA) are at the center stage of modern web development. Top notch web applications depends on fast and responsive behaviour in both user interface and data. Hence the popularity of frameworks like React, Angular, Vue and Ember.

This blog post shows how you can get started with React and restdb.io for development of applications with realtime data.

React is an amazing piece of technology. With it's realtime DOM manipulation and component thinking, it's just a perfect match for realtime enabled databases and frameworks like Firebase, RethinkDB, Pusher and RestDB.io.

In this blog post we'll be developing an application for displaying Nasdaq stock information.

The demo code is nothing fancy, but focuses on showing how to set up up your React application, and connect it to a real time data stream and a REST API.

Highlights

  • Standard web browser Eventsource API to connect to the restdb.io real time API
  • Axios for communication with the REST API
  • Dump of Nasdaq stock data stored in the database
  • Deploy the finished application to a restdb.io server

The screen shot below shows what the finished app looks like:

finished app

You can check out a live demo at this link.

Lets look at how this application is made.

Create the project

Create a directory and install the wonderfully easy-to-use npm package create-react-app.

mkdir react-demo
cd react-demo/
npm install -g create-react-app
create-react-app realtime-react
cd realtime-react

Utilities

In addition to React we need Axios for REST communication and Lodash for convenience.

# the -S option adds it to our package.json project file
npm install axios -S
npm install lodash -S

Create the database

After creating a new database in restdb.io, we begin with importing data from a local csv file downloaded from the web:

name,symbol,open,high,low,close,net chg,percent chg,volume,52 wk high,52 wk low,div,yield,P-E,ytd percent chg
1st Constitution Bancorp,FCCY,17.30,17.50,17.25,17.25,...,...,"2,900",20.85,11.83,0.20,1.16,15.83,-7.75
1st Source,SRCE,48.11,48.89,48.02,48.67,0.44,0.91,"31,238",50.77,31.88,0.76,1.56,21.07,8.98
2U,TWOU,45.23,46.37,45.08,46.24,1.30,2.89,"280,877",48.40,29.23,...,...,...,53.37
...

Because these data are from the Nasdaq stock exchange, we import the data into a new collection that we named nasdaq.

After the import we can look at the data inside in the restdb.io data manager:

stock data in restdb.io

Yay! The data schema has been created automatically from the import data:

schema

This gives us the following REST endpoint for our stock data:

https://reactrealtime-6683.restdb.io/rest/nasdaq

Which will output a JSON document like the following:

{
    _id: "596335cd2b769915000007a6"
    name: "1st Constitution Bancorp"
    symbol: "FCCY"
    open: 17.3
    high: 17.5
    low: 17.25
    net chg: null
    percent chg: null
    volume: 2
    52 wk high: 20.85
    52 wk low: 11.83
    div: 0.2
    yield: 1.16
    P-E: 15.83
    ytd percent chg: -7.75
    price: 17.25
},
...

Secure CORS

In order to allow clients to communicate with our database we must create a CORS api key with a connection profile. The secure CORS key is created in restdb.io under the database settings section:

The screen shot below shows the set up of both REST and Realtime:

cors

The settings above reads like this:

  • Allow client to send GET PUT REST API operations from * (any) domain.
  • Allow client to listen for realtime events on POST PUT DELETE operations to :* (any) collection

The database is now ready, and we can move on to create our React application.

Create the React application

The application consist of 3 main source files (in addition to React files and html,css ..)

  • helper.js - global settings
  • App.js - App component, Ticker component for stock list and realtime changes
  • Autotrader.js - Trade component for sending emulated stock price changes to the database

Global settings

To keep things DRY we'll create a helper file helper.js which will contain our global application settings.

// helper.js
import axios from 'axios';

// CORS enabled apikey
const apikey = '5x5fx501xfcex9e87x11ex6x';

// Autotrade delay
const trade_delay = 10000; // millis

// REST endpoint
let restdb = axios.create({
    baseURL: 'https://reactrealtime-6683.restdb.io',
    timeout: 1000,
    headers: { 'x-apikey': apikey }
});
// Eventsource endpoint
const realtimeURL = `https://reactrealtime-6683.restdb.io/realtime?apikey=${apikey}`

export { apikey, restdb, realtimeURL, trade_delay };

Main App component

In our App.js file we have 2 components, App and Tickers. App is the main component with the App container, and Tickers renders the stock list data and refreshes on realtime changes.

The code snippet below show the main container of our application, a heading and two components, Trade and Tickers.

class App extends Component {
  componentDidMount() {
    // start trading
  }
  render() {
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>React &amp; RestDB.io in Realtime</h2>
        </div>
        
        <h2>Nasdaq trading bots <small>fake</small></h2>
        <Trade/>
        <Tickers/>
      </div>
    );
  }
}

Connecting the Eventsource to a realtime stream

We can listen for realtime database changes via the browser EventSource API.

// connect to the realtime database stream
let eventSource = new EventSource(`https://reactrealtime-6683.restdb.io/realtime?apikey=${apikey}`);

To make sure the connection is valid you can view the live stream from your browser network inspector, shown in the screen shot below: inspect realtime stream

The inspector shows that we are receiving server events for putand ping. The putevents are changes in our nasdaqdata collection. And the ping events are keep-alive messages from the server. We will use this to make sure we can re-connect to the EventSource if/when the client loose connection to the server.

The trick is to store a time stamp for the last pingmessage. This code snippet shows how we add this to the component state:

// listen on ping from server, keep time
eventSource.addEventListener('ping', function(e) {
    this.setState(previousState => {
      return {ping: new Date(e.data)};
    });
}.bind(this), false);

We can now, in an interval, check how long time has passed since the client last got a ping message from the server. If that time span is too long (e.g. 20 sec), we re-connect our client.

// check if the realtime connection is dead, reload client if dead
setInterval(() => {
  let now = new Date().getTime();
  let diff = (now - this.state.ping.getTime()) / 1000;

  // haven't heard from the server in 20 secs?
  if (diff > 20) {
    // hard reload of client
    window.location.reload();
  }
}, 10000);

The Ticker component

The Ticker component retrieves stock data from the database. It also listens for realtime events when data has changed.

// App.js
import React, { Component } from 'react';
import _ from 'lodash';
import logo from './logo.svg';
import './App.css';
import Trade from './Autotrader';
import { restdb, realtimeURL } from './helper.js';


class Tickers extends Component {
  constructor(props) {
    super(props);
    
    this.state = {ping: new Date(), evt: '', tickers: []};
    
    // connect to the realtime database stream
    let eventSource = new EventSource(realtimeURL);

    // check if the realtime connection is dead, reload client if dead
    setInterval(() => {
      let now = new Date().getTime();
      let diff = (now - this.state.ping.getTime()) / 1000;
      
      // haven't heard from the server in 20 secs?
      if (diff > 20) {
        // hard reload of client
        window.location.reload();
      }
    }, 10000);
    
    // listen on ping from server, keep time
    eventSource.addEventListener('ping', function(e) {
        this.setState(previousState => {
          return {ping: new Date(e.data)};
        });
    }.bind(this), false);
    
    // listen for database REST operations
    eventSource.addEventListener('put', (e) => {
        this.getTickerData()
        
    }, false);
    
  }

  // GET 20 stocks to display and trade
  getTickerData = () => {
    restdb.get("/rest/nasdaq?sort=symbol&max=20&metafields=true")
      .then(res => {
        let now = new Date().getTime();
        let tickers = res.data;
        let diff = null;
        
        // tag stocks that are changed in the last 10 secs
        _.each(tickers, (t) => {
          diff = (now - new Date(t._changed).getTime()) / 1000;
          if (diff < 10) {
            t.isChanged = true;
          } else {
            t.isChanged = false;
          }
        });
        
        this.setState(previousState => {
          return { tickers };
        });
      });
  }
  componentDidMount() {
    console.log("Start client");
    this.getTickerData();
  }

  render() {
    return (
      <div className="tickers">
        <table className="table">
          <thead>
            <tr>
              <th>Symbol</th>
              <th>Company</th>
              <th className="num">Price</th>
              <th className="num">Change</th>
            </tr>
          </thead>
          <tbody>
            
            {this.state.tickers.map(tic =>
              
              <tr key={tic._id} className={tic.isChanged ? (tic['net chg'] > 0 ? "up" : "down") : "passive"}> 
                <td>{tic.symbol}</td>
                <td>{tic.name}</td>
                <td className="num">{tic.price.toFixed(2) || 0.0}</td>
                <td className="num">{tic['net chg'] ? tic['net chg'].toFixed(2) : 0.0}</td>
              </tr>
            )}
            
          </tbody>
        </table>
      </div>
    );
  }
}

The Trading component

Our last file Autotrader.js contains one component Trade. The component sends updates (PUT) to a random stock from the list each 10th second.

import React, { Component } from 'react';
import { restdb, trade_delay } from './helper.js';

// emulate price change on stocks
class Trader extends Component {
    constructor(props) {
        super(props);
        this.state = {stocks: [], lasttrade: null};
        
        // GET 20 stocks
        restdb.get("/rest/nasdaq?sort=symbol&max=20")
        .then(res => {
            const stocks = res.data;
            this.setState(previousState => {
                return { stocks };
            });
        });

        // update a random stock each 10 sec
        setInterval(() => {
            let stockpos = Math.floor(Math.random() * 19);
            if (this.state.stocks[stockpos]) {
                let stockID = this.state.stocks[stockpos]._id;
                let newprice = (Math.random() * 1000.0) + 1.0;
                // PUT new price on one stock
                restdb.put(`/rest/nasdaq/${stockID}`,
                    {price: newprice}
                )
                .then((response) => {
                    
                    this.setState(previousState => {
                        return {lasttrade: response.data};
                    });
                })
                .catch(function (error) {
                    console.log(error);
                });
            }
        }, trade_delay);
    }
    
    render() {
        return (
        <div className="autotrade">
            <p>Trading: {this.state.lasttrade ? (this.state.lasttrade.symbol + ' at ' + this.state.lasttrade.price.toFixed(2)) : 'none'}</p>
        </div>
        );
  }
}

export default Trader;

Server Codehook for validation of stock price change

Our final piece of code is for server side validation of PUT operations against our nasdaq database collection. We will create a database Codehook that triggers on beforePUT. This function validates that the new price if not negative, and it calculates the diff between the new and the old price. The diff is then stored in a property called ['net chg'].

// Codehooks for nasdaq
function beforePUT(req, res) {
    
    // fetch old value first
    let query = {_id: req.body._id};
    let hint = {};
    
    db.get("/rest/nasdaq", query, hint, function (err, result) {
        
        // set the delta value as old - new value
        req.body['net chg'] = req.body.price - result[0].price;
        req.body.price = Math.max(req.body.price, 0.0);
        // return the updated document
        res.end({"data": req.body});    
    });
    
}

This concludes our simple React application. The next step is to run and test it locally and then deploy it to the restdb.io server.

Run application from a local Node.js server

If you install Node.js on your local machine you can take advantage of the rapid development cycle with hot code re-loading and debugging. The create-react-app npm package has a command that spins up a Node server on our local machine.

# start a local node.js server
npm start

You should see something like this output in your terminal window:

npm start

You can now test you app from http://localhost:3000.

Build application

To create a packaged application that can be deployed, you can use the handy build command.

npm run build

After the build you should see something similar to this:

build

Run static file server to test build

You can also test your deploy-ready package on a local HTTP server. Here we use the npm package serve:

serve -s build

You should see this output in the terminal window:

static server

You can now test you deployment app package from http://localhost:5000.

Our final step is to deploy our application to the world. We can deploy our React app to a variety of HTTP servers, but in this example we'll be using the restdb.io server. Loading the app from the same server/domain that contains the data gives us a significant speed improvement.

Deploy application to restdb.io

restdb.io has a built in web server that lets you deploy and serve static files.

E.g. https://<yourdbname>.restdb.io/static

You can deploy to your database with the restdb-cli command line tool.

To deploy our React app, we run the following command:

restdb-cli --cmd upload --src ./build --dest /reactapp --database reactrealtime-6683 --apikey 
<your full access api-key here>

However, a much better approach is to add this as a deployment command to our application package.json file instead.

Also, adding relative paths to the build folders lets us deploy both locally and to a server with a different folder structure. We do this by setting the "homepage": "." property in the package.json file. Our final package.json file looks like this:

{
    "name": "realtime-react",
    "version": "0.1.0",
    "private": true,
    "homepage": ".",
    "dependencies": {
        "axios": "^0.16.2",
        "lodash": "^4.17.4",
        "react": "^15.6.1",
        "react-dom": "^15.6.1",
        "react-scripts": "1.0.10"
    },
    "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test --env=jsdom",
        "eject": "react-scripts eject",
        "deploy": "restdb-cli --cmd upload --src ./build --dest /reactrealtime --database reactrealtime-6683 --apikey <your full access api-key here>"
    }
}

Lets run the deploy command.

npm run deploy

If all goes well, it should display something like this:

> realtime-react@0.1.0 deploy /Users/joneriksolheim/projects/react-demo/realtime-react
> restdb-cli --cmd upload --src ./build --dest /reactrealtime --database reactrealtime-6683 --apikey xxxxxxxxxxxxxxxxxxx


Upload successful!  3398298 total bytes uploaded

The deployed application is now served from restdb.io server at this URL:

https://reactrealtime-6683.restdb.io/static/reactrealtime/build/index.html

Conclusion

Coding a realtime app with React is fun, and a lot easier than you might think. Simple state management with automatic DOM sync makes our code clean and small. Using the browsers standard EventSource API to listen for realtime data events are both simple and effective. And finally, using Axios for REST communication just rocks.

View full source code on GitHub here.

Further reading

  • restdb.io realtime docs
  • restdb.io rest api docs
  • restdb-cli command line docs
  • restdb.io codehooks docs
  • create-react-app
  • axios
  • Eventsource API
  • Share on Facebook
  • Tweet
  • Add to Pocket
  • Share on LinkedIn
  • Send email

All Posts


Search

Topics

  • API
  • Authentication
  • Case study
  • Features
  • Howto
  • Integrations
  • Newsletter
  • Productivity
  • Prototyping
  • Tutorials
  • User

restdb.io is a fast and simple NoSQL cloud database service. With restdb.io you get schema, relations, REST API and an efficient multi-user admin UI for working with data.

Our customers use it for backends, business databases, API-first CMS, data collection and much more. It is easy to get started with the free development plan.

Start Building »

  • Site Links
  • Home Page
  • About Us
  • Contact
  • Blog
  • Templates Catalog
  • Cloud Service
  • Features
  • Pricing
  • Terms & Conditions
  • Privacy Policy
  • Sign Up »
  • Documentation
  • Overview
  • Getting Started
  • Coding against the API
  • Utils
  • Security and Admin
© 2025 restdb.io