Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access another modules store with ngrx's StoreModule.forRoot() and StoreModule.forFeature()

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.

like image 441
John Avatar asked Feb 04 '18 13:02

John


People also ask

How do I change the state of the ngrx store?

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.

What is an immutable object in ngrx?

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.

What is the use of store in angular?

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:

What are selectors in ngrx/store?

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.


1 Answers

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.

like image 52
mgajic Avatar answered Sep 30 '22 19:09

mgajic