why deepstreamHub? compare us getting started feature roadmap faq
use cases pricing
developers
company
enterprise blog contact

You probably know the TodoMVC project (if not, take a look). We believe that deepstreamHub's lists and records can simplify the development and implementation of many kinds of project, ToDomvc and the like are good examples for that. This tutorial will show you how to use deepstreamHub's records and lists for building a realtime TodoList app with React. We definitely recommend being familiar with Records and Lists before giving this a go, and, of course, with the React framework.

This is how it looks like:

todoMVC gif

Create a free account and get your API key

Connect to deepstreamHub and log in

Include the JS-client library

<script src="//cdnjs.cloudflare.com/ajax/libs/deepstream.io-client-js/2.1.1/deepstream.js"></script>

Get your app url from the dashboard and establish a connection to deepstreamHub

var ds = deepstream( '<YOUR APP URL>' );

and log in (we didn't configure any authentication, so there are no credentials required)

ds.login();

Getting the list and subscribing for updates

Include this in your main component's constructor/getInitialState section:

    this.list = ds.record.getList( 'todos' );
    this.list.subscribe(this._setEntries.bind( this ) );

Then set the setEntries function that keeps listening to changes in the list (new entry, removed entry):

_setEntries( entries ) {
    this.setState({
      todos: entries
    });
  }

This.state.todos is an array of record names (entries) retrieved from the list. Now, with this binding, each time a todo item is added or removed, the state of the component is automatically updated. Each todo item is rendered separately in a different component, being passed a recordName. Every time the TodoItem component is initiated, it uses the recordName to get the details from the actual record. This is what should be included in the TodoItem's constructor/getInitialState section:

this.record = ds.record.getRecord(this.props.recordName);
this.record.subscribe(this.setState.bind(this), true);

In that way, first of all, all the data of the record is being retrieved, in this case - the title and the isDone, passed to the state of the component, and rendered. Then, each time there's an update in the record, for example the title is edited, the state of the element is automatically updated (after updating the record), and the component re-rendered.

Adding/removing/updating ToDo items

Whenever a text is being entered in the input field, two things should happen - a record should be initiated, and the list should get a new entry. This is the function that's being called when a new Todo is in:

addTodo() {
    var id = 'todo/' + ds.getUid();
    ds.record.getRecord(id).set({
      title: this.state.newTodo,
      isDone: false
    });
    this.list.addEntry( id );
  }

As you can see, first a unique id is being created, then a record is being created with the unique id name, the title from the input field, and a default 'isDone' property that is being set to 'false'. Also, an entry is being added to the list, which automatically sets the state, which makes the whole thing render again with the new record. When the delete button is being pressed, a function like this should be invoked:

removeTodo() {
    this.props.list.removeEntry( this.record.name );
    this.record.delete();
  }

To update a record, for example the title, use this:

        this.record.set('title', title);

In case all the checkboxes are checked, and the "Clear Completed" button is being pressed, this how you would empty the whole list:

      list.setEntries([]);

For the full code, please take a look at the GitHub repository.