Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ngrx state is undefined

Tags:

angular

ngrx

I'm attempting to encapsulate my ngrx state in a shared service class to abstract the implementation details away from my components.

Example service class that is registered in my app.module.ts providers

@Injectable()
export class PatientService {

  state: Observable<PatientState>;

  constructor(
    private store: Store<AppState>,
  ) {
    this.state = store.select<PatientState>('patients');
  }

}

I have verified my actions, reducer and effects are working as expected, however, when I subscribe to the service state in a component, it returns undefined.

Example component subscription using the shared service:

@Component({
  ...
})
export class DashboardComponent implements OnInit {

  constructor(
    private patientService: PatientService,
  ) {}

  ngOnInit(): void {
    // dispatches action to load patient from API
    this.patientService.loadPatient();

    this.patientService.state.subscribe(patientState => {
        console.log('patientState', patientState);
        // Does not work. Logs undefined.
    });
  }

}

If I subscribe directly to the store, it works as expected.

Example:

@Component({
  ...
})
export class DashboardComponent implements OnInit {

  constructor(
    private patientActions: PatientActions,
    private store: Store<AppState>,
  ) {}

  ngOnInit(): void {
    this.store.dispatch(this.patientActions.loadPatient());

    this.store.select<PatientState>('patients').subscribe(patientState => {
        console.log('patientState', patientState);
        // Works as expected.
    });
  }

}

What am I doing wrong?

like image 273
Brandon Avatar asked Mar 12 '17 02:03

Brandon


People also ask

What is a state in NgRx?

NgRx is a framework for building reactive applications in Angular. NgRx is inspired by the Redux pattern - unifying the events in your application and deriving state using RxJS. At a high level, NgRx stores a single state and uses actions to express state changes.

Is NgRx necessary for Angular?

NgRx is a popular solution in the Angular ecosystem if you are building complex web applications with sophisticated state management. Characteristics of the need for NgRx are many user interactions and multiple data sources. NgRx is a good choice, if: the state should be accessed by many components and services.

Where is NgRx state stored?

Where Does NgRx Store Data? NgRx stores the application state in an RxJS observable inside an Angular service called Store. At the same time, this service implements the Observable interface.


1 Answers

I solved this by following Mergasov's advice and set a default case condtion:

I had the similar issue: when a component subscribes to state it gets state === undefined always. It was very confused for me, but finally I've found corresponding reducer is not implemented magic code: default: return state;

Here's how that looks in the context of a larger reducer.ts:

  export function reducer(state: EntityState= initialEntityState, action:  actions.EntityAction) {
    switch (action.type) {
      case actions.CREATE_ENTITY_SUCCESS:
      case actions.UPDATE_ENTITY_SUCCESS: {
        const EntityDetails = action.payload;
        const entities = {
          ...state.entities,
          [Entitydetails.Id]: EntityDetails,
        };
        return {
          ...state,
          error: null,
          entities,
        };
      }
      default : {
        return state;
      }
    }
 }

Previously, my code did not have a default condition, and was returning undefined due to that fact. adding the default condition to the reducer resolved the issue.

like image 188
George Stocker Avatar answered Oct 07 '22 14:10

George Stocker