Adding a store

A store at its heart is just a class wrapping a state. A store needs to be able to deal with changes;  the change should come via method dispatch. The following pseudo code represents what the store might look like:

// NGRX-light/storeI.js

class Store {
constructor() {
this.state = {};
}
dispatch() {
// calculate the new state and replace the old one
}
}

We mentioned in the beginning of this main section that NgRx uses RxJS at its core. We mentioned that it was so the store could convey changes to its listeners. Let's mention the core concepts of RxJS that might fit the preceding problem description. In RxJS, we have:

  • Observable: It is able to emit values and you can attach subscribers to it
  • Observer: This is the object that is called so that we end up getting the values as a subscriber
  • Subscriber: This is a combination of an Observable and an Observer in that it can be subscribed to but it is also possible to add values to it after the subscription has happened.

Thinking about the store for a bit, we realize we need to be able to add values to it at any point and we need to be able to subscribe to it. This seems to fit the behavior of the Subject. Let's continue our pseudo coding of the Store but let a Subject be part of it now:

// NGRX-light/storeII.js

class Store {
constructor() {
this.state = {};
}

dispatch(newState) {
this.state = newState;
}
}

We implemented the dispatch() method with the following code: 

this.innerSubject.next(newState);

For now, let's care about implementing subscription functionality. Let's imagine the store will be used in the following way:

const store = new Store();
store.subscribe(data => {
console.log('data', data);
})

For that to be possible, we could just add the subscribe() method to our store. If we were to do that ourselves, we would have to take care of a list of listeners and ensure listeners are told when a change happens to the state. A better option is to just let our store inherit from Subject. That would take care of the subscription bit. Let's see what that might look like:

// NGRX-light/storeIII.js

const Rx = require('rxjs');

class Store extends Rx.Subject {
constructor() {
super();
this.state = {};
this.subscribe(data => this.state = data);
}

dispatch(newState) {
this.next(newState);
}
}

const store = new Store();
store.subscribe(data => console.log('store', data));

store.dispatch({});
store.dispatch({ user: 'chris' });

// store {}
// store { user: 'chris' }

The preceding code reimplements the dispatch() method and we also set up a subscription in the constructor to ensure our latest state is updated. There is a thing we need to improve here and that is how we add state to our store. With Redux, the incoming state change should be reduced into the old state, like so:

const store = new Store();
store.subscribe(data => console.log('store', data));
// desired behavior: store { name: 'chris' }
// desired behavior: store { name: 'chris', address: 'London' }

store.dispatch({ name : 'chris' });
store.dispatch({ address : 'London' });

The way to achieve this is to refactor our code a little and create another Subject that will be the target of a call to dispatch, like so:

// NGRX-light/storeIV.js

const Rx = require('rxjs');

class Store extends Rx.Subject {
constructor() {
super();
this.dispatcher = new Rx.Subject();
this.state = {};
this.dispatcher.subscribe(data => {
this.state = Object.assign({}, this.state, data);
this.next(this.state);
});

}

dispatch(newState) {
this.dispatcher.next(newState);
}
}

const store = new Store();
store.subscribe(data => console.log('store', data));

// store { name: 'chris' }
// store { address: 'London' }

store.dispatch({ name: 'chris' });
store.dispatch({ address: 'London' });
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.11.227