James D
James D

Reputation: 2291

How to use a selector from another feature with NGRX

I have a page for an administrator where I have a state for that specific page. I also want to show parts of the report state. In the redux devtools I can see I've properly loaded the reports and initialized the admin piece of state, but I can't get my selectors to access the reports piece of the state.

I've went through the official documentation, but separate file multi selectors isn't clear to me ref official docs. I've adjusted my state to inherit from the main state, but that was clearly wrong. I've made some other adjustments and I've been searching google all day long, but so far in vain.

wageAdmin Part

in the admin shell component I have

ngOnInit(): void {
// this works
    this.store.dispatch(new fromReportActions.Load());
    this.showReportCode$ = this.store.pipe(select(fromWageAdmin.getShowWageAdminCode)); 

// this returns undefined
    this.reports$ = this.store.pipe(select(queryReports.getReports)); 
    this.errorMessage$ = this.store.pipe(select(queryReports.getError)); 
    this.selectedReport$ = this.store.pipe(select(queryReports.getCurrentReport)); 
    this.displayCode$ = this.store.pipe(select(queryReports.getShowReportCode)); 
  }

redux image

in the admin module I'm importing

    StoreModule.forFeature('wageAdmins', reducers),
    EffectsModule.forFeature(
      [ WageAdminEffects, ReportEffects ]
    ),

in the index.ts from my admin state i have

import { createFeatureSelector, createSelector, ActionReducerMap } from '@ngrx/store';
import * as fromRoot from '../../state/app.state';
import * as fromWageAdmin from './wageadmin.reducer';
import * as fromReports from '../../state/report/report.reducer';

export interface State extends fromRoot.State {
    wageAdmins: fromWageAdmin.WageAdminState;
}

export const reducers : ActionReducerMap<State> = {
    wageAdmins: fromWageAdmin.reducer,
    reports: fromReports.reducer
}

// Selector functions
export const getWageAdminFeatureState = createFeatureSelector<fromWageAdmin.WageAdminState>('wageAdmins');

export const getShowWageAdminCode = createSelector(
    getWageAdminFeatureState,
    state => state.showReportCode
);

in the wageadmin.reducer.ts i have

import { WageAdminActionTypes, WageAdminActions } from './wageadmin.actions';

// State for this feature (WageAdmin)
export interface WageAdminState {
  showWageAdminCode: boolean;
  wageAdminError: string;
}

const initialWageAdminState: WageAdminState = {
  showWageAdminCode: true,
  wageAdminError: ''
};

export function reducer(state = initialWageAdminState, action: WageAdminActions): WageAdminState {
// etc....

Report Part

In the app.state.ts file in the top level of my app I have

import * as fromReports from './report/report.reducer';

export interface State {
  reports: fromReports.ReportState
}

export { queryReports } from './report/report.selectors';
export { fromReportActions } from './report/report.actions';

in the report.reducer.ts I have

import { Report } from '../../classes/report';
import { ReportActionTypes, ReportActions } from './report.actions';

// State for this feature (WageAdmin)
export interface ReportState {
  showReportCode: boolean;
  currentReportId: string | null;
  reports: Report[];
  error: string;
}

export const initialState: ReportState = {
  showReportCode: true,
  currentReportId: null,
  reports: [],
  error: ''
};

export function reducer(state = initialState, action: ReportActions): ReportState {
// etc......

In the my report.selectors.ts

import { Transport } from 'src/app/classes/transport';
import { Report } from 'src/app/classes/report';

import { createFeatureSelector, createSelector } from '@ngrx/store';
import * as fromReports from './report.reducer';

// Selector functions
export const getReportFeatureState = createFeatureSelector<fromReports.ReportState>('reports');
export const getReports = createSelector(
    getReportFeatureState,
    state => state.reports
);

Output

I expected the report state, but I'm getting console error output of

Upvotes: 4

Views: 4796

Answers (1)

James D
James D

Reputation: 2291

I was wrong to combine the reducers at the wageAdmin level.

wrong redux implementation

I removed reducers from index.ts in wage admin part. Then in the module part I changed the imports to

    StoreModule.forFeature('wageAdmins', reducer),
    EffectsModule.forFeature(
      [ WageAdminEffects ]
    ),

And then in the module where I build the reports, report.module.ts, I import the reports store and reducer


    StoreModule.forFeature('reports', reducer),
    EffectsModule.forFeature(
      [ ReportEffects ]
    ),

After this change my code runs as it should correct redux implementation

Upvotes: 4

Related Questions