Last update on Wednesday, August 23rd 2017

Implementing Redux Time Travel in an Ionic Application

Implementing an Undo Redo System (or Time Traveling) in an Ionic application can be complex, we have to keep in memory states, changes, actions, bindings and this is a huge headache.
On the other side if we use Redux, this can be done with 10-20 lines of code.
So let's use this baby!
This tutorial is the continuation of the previous one so be sure to take a look there if you need more information on how to setup Redux or why we should use it.

We are going to display two new information:

  1. The whole States history
  2. The previous State

Let's start by adding the Redux undo library:

npm install --save redux-undo

Template

The home.html file will be updated as follow:

<ion-content padding>

  What happened in the past:

  <div>
    {{previousColorList$ | async | json}}
  </div>

  Our previous state:

  <div>
    {{previousState$ | async | json}}
  </div>

  What we have at the moment:
  ...
</ion-content>

We won't show the previous States by using squares otherwise it will be difficult to analyze. Two arrays will be shown there thanks to the async and json Pipe.
The async Pipe will handle the Observables that are returned and the json will format the data.

The last addition at the end of this file:

<ion-content>
  ...
  <button ion-button (click)="undo()">
    Undo
  </button>

  <button ion-button (click)="redo()">
    Redo
  </button>

</ion-content>

Those two buttons will trigger the undo and redo methods allowing us to jump back and forward.

TypeScript

We can now move to the home.ts file:

var reduxLogger = require('redux-logger');
var undoable = require('redux-undo');

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  ...
}

The Redux Undo plugin isn't an Angular library so we can't add it to the app.module file nor inject it in our Ionic application.
This is still JavaScript so we can still acquire it by using the require method.

This library will change the structure of our Redux Store as follow:

ionic redux time travel undo redo structure

We are going to acquire the data from the past and present properties in the home.ts file:

export class HomePage {
  @select(['present', 'colorList']) currentColorList$;
  @select(['past']) previousColorList$;
  @select(store => { return store.past.slice(-1) }) previousState$;
  ...
}

The select Decorator is now fully used:

  • The currentColorList$ property will have the store.present.colorList information
  • The previousColorList$ property will have the past information
  • The previousState$ property is a bit more tricky. The select Decorator returns our Store, from there, the past property is an array containing the previous States. We only need to grab the last element.

The properties our now ready!

We now need to drop by the HomePage constructor to allow the Time Traveling feature:

  constructor( public store: NgRedux<ColorListState>, public colorActions: ColorActions, public devTools: DevToolsExtension) {

    store.configureStore(
      undoable.default(colorReducer),
      INITIAL_STATE,
      [ reduxLogger.createLogger()],
      devTools.isEnabled() ? [ devTools.enhancer() ] : []);

    colorActions.loadColors();
  }

It's very simple.
The only modification here is using the undoable.default method to transform our colorReducer and that's it, we are good to go!

Here is our application:

ionic redux time travel undo redo init

Final step: adding the undo and redo methods:

  undo() {
    this.store.dispatch(undoable.ActionCreators.undo())
  }

  redo() {
    this.store.dispatch(undoable.ActionCreators.redo())
  }

Once again, those methods are very simple.
Some new Redux Actions are dispatched on the Redux Store. Those Actions are created by the undoable library. They are located in the ActionCreators property and ready to be used.

Here is our time travel feature in action:

ionic redux time travel undo redo init

Impressive right?

Conclusion

Implementing Redux in an Ionic application can be quite a task (I have dedicated a whole tutorial on that). Once this is done, we can easily add new complex features without breaking a sweat.
In this case, we only need to install the redux-undo library, wrap it around our Reducer and dispatch the library's Actions to our Store. This Time Travel feature generally takes a lot of brainpower and hours, here it's done in 10 minutes.

Adding Redux to an Ionic Application

Implementing GraphQL using Apollo in an Ionic Application: CRUD

Using Vue as an Angular alternative for Ionic: Vuex in One Go

Stay up to date


Join over 4000 other developers who already receive my tutorials and their source code out of the oven + other free stuff!