angularngrxngrx-store

Ngrx latest version, can't retrieve the data from the store


I am trying to use ngrx in my angular project but for some reason I am unable to retrieve and show data and i have tried everything i could find in the internet, i am using the latest version of angular and ngrx. In the console when i click on "test" in home.html, it is showing that the state of "MyBoolean" is changing in the store but i just can't retrieve it from the store. Thanks for the help and your time.

main.ts

bootstrapApplication(AppComponent, appConfig)
  .catch((err) => console.error(err));

app.config.ts

import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';

import { routes } from './app.routes';
import { provideStore } from '@ngrx/store';
import { reducers, metaReducers } from './reducers';

export const appConfig: ApplicationConfig = {
  providers: [provideRouter(routes), provideStore(reducers, { })]
};

reducers/index.js

import { reducer } from "./homeReducer"
import { isDevMode } from '@angular/core';
import {
  ActionReducer,
  ActionReducerMap,
  createFeatureSelector,
  createSelector,
  MetaReducer
} from '@ngrx/store';

export const reducers: ActionReducerMap<any> = {
  homeReducer: reducer
};


export const metaReducers: MetaReducer<any>[] = isDevMode() ? [] : [];

reducers/homeReducer.ts

import { createReducer, on } from '@ngrx/store';

import { toggleBoolean } from '../actions/home.actions';

export interface State {
    MyBoolean: boolean;
}

export const initialState: State = {
    MyBoolean: false,
};

export const featureReducer = createReducer(
    initialState,
    on(toggleBoolean, (state) => {
        console.log(state)
        const s = { ...state, MyBoolean: !state.MyBoolean }
        return s;
    })
);

export function reducer(state: State | undefined, action: any) {
    return featureReducer(state, action);
}

home.component.ts

import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { RouterModule } from '@angular/router';

import { Observable } from 'rxjs';
import { Store } from '@ngrx/store';
import { toggleBoolean } from '../actions/home.actions'; 
import { CommonModule } from '@angular/common';



@Component({
  selector: 'app-home',
  standalone: true,
  imports: [RouterOutlet, RouterModule, CommonModule],
  templateUrl: './home.component.html',
  styleUrl: './home.component.css'
})
export class HomeComponent {

  MyBoolean$: Observable<boolean>;

  constructor(private store: Store<{ MyBoolean: boolean }>) {
//  this.MyBoolean$ = this.store.select("MyBoolean");
    this.MyBoolean$ = this.store.select(store => store.MyBoolean);
  }

  toggleBoolean() {
    this.store.dispatch(toggleBoolean());
  }
}

home.component.html

<div>
<button type="button" (click)="toggleBoolean()">test</button>
<h1>boolean: {{ MyBoolean$ | async }}</h1>
</div>

app.routes.ts

import { Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';

export const routes: Routes = [{
    path: 'home',
    component: HomeComponent,
    title: 'Home page'
}];

Solution

  • The best approach is to use selector to obtain slices of store state. Exemple :

    providers: [
    …
     provideStore(),
     provideState({ name: ‘featureKey’, reducer: reducer })
    ]
    

    export const selectFeature = createFeatureSelector<State>(‘featureKey’);
        
    export const selectMyboolean = createSelector(
          selectFeature,
          (state: State) => state.Myboolean
        );
    

    MyBoolean$ = this.store.select(this.selectMyboolean);