Building an angular5 app... so many moving parts compared to vue or react, but i'm sticking with it.
Making use of angulars lazy loading of modules I am producing each page in angular as a module. Each module has its own encapsulated store using ngrx's:
StoreModule.forFeature('home', HomeReducer),
So far so good.. we can easily inject data into the HomePages store with the module looking a little like this:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { EffectsModule } from '@ngrx/effects';
import { StoreModule } from '@ngrx/store';
import { HomeComponent } from './home.component';
import { HomeRoutingModule } from './home-routing.module';
import { HomeReducer } from '@modules/page/home/redux/home.reducers';
import { HomeEffects } from '@modules/page/home/redux/home.effects';
import { HomeService } from '@modules/page/home/home.service';
@NgModule({
declarations: [
HomeComponent
],
imports: [
CommonModule,
HomeRoutingModule,
StoreModule.forFeature('home', HomeReducer),
EffectsModule.forFeature([HomeEffects])
],
exports: [],
providers: [
HomeService
],
})
export class HomeModule {
}
The component is also quite simple and looks like this:
import { Component, OnInit } from '@angular/core';
import * as homeActions from './redux/home.actions';
import { Store } from '@ngrx/store';
import { HomeState } from '@modules/page/home/redux/home.state';
import { Observable } from 'rxjs/Observable';
@Component({
selector: 'app-home-component',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
cars: Observable<any>;
constructor (private store: Store<HomeState>) {
this.cars = this.store.select(homeActions.getCars);
}
ngOnInit () {
}
clickme () {
// dispatch a fetch to the store. gallery of images.
// todo add a propper type model
const imageType: any = {
type: 'cars'
};
this.store.dispatch(new homeActions.GalleryFetch(imageType));
}
}
The clickme
function dispatches and action which is listened by the effects which in turns triggers another action on successful http request which finally places the data into the view...
But now the obvious next step.. i need to share this data with another page. Two questions immediately come to mind
1 - What is the best way to access one modules store data from another module?
2 - What is the point of encapsulating the module data like this if it needs to be shared with another module, eg a login module will always need to share the user data.. is the answer to only use this forFeature()
for data that really will only be used by the module?
IMHO: Splitting state into modules is a nice ideology for the ultimate practice of reusable chunks of code. I mean to write a self contained module and simply drop it into your app is great... but an app will nearly always need to pass data from one module to the next, and when this needs to happen broken state into modules creates more issues than it solves.
The NgRX Store models a state as a single and simple JavaScript object inside the Store. The state is immutable or read-only. This means that there is no direct Store API to change the state object inside the Store. There are other means of updating the state that I will be discussing soon.
An immutable object is an object whose state doesn't change after creation. During the set up of ngrx/store module, as you will see later in this article, you configure the StoreModule class with a map among all available state segments in the application with their corresponding reducers.
The Store acts like a container for the state in the ngrx/store module. In addition, Angular components inject the Store into their constructors to establish the communication channel. The Store exposes two methods used by the Angular components. By injecting the Store, a component can have access to the following functions:
Selectors are pure functions that take slices of the state as input arguments and return slices of state data that components can consume. Just as databases have their own SQL query language, ngrx/store module has its own query tools that are the Selectors.
You just need to import the HomeModule into another module, so in that way the home feature's store and effects will be registered in that new module as well. After that, you need to define the home feature's store in the constructor of the new module's component and you will be able to use it as you do in the HomeModule.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With