Johansrk
Johansrk

Reputation: 5250

Trying out NGRX, but the value from the store is an abject instead of a number

I have made a little project to try out NGRX for Angular. The code should increment or decrement the counter in the store. It works, except the return value from the store is {counter: 1}, where I would expect 1

this is my code

Counter Component

import { Component, OnInit } from "@angular/core";
import { select, Store } from "@ngrx/store";
import { decrement, increment } from "./state/app.actions";
import { AppState } from "./state/app.state";

@Component({
  selector: 'app-counter',
  template: `
    <div>
      <h2>Counter: {{ counter }}</h2>
      <button (click)="onIncrement()">Increment</button>
      <button (click)="onDecrement()">Decrement</button>
    </div>`
  })
  export class CounterComponent implements OnInit {
    counter: number;

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

    ngOnInit() {
      this.store.pipe(select((state: AppState) => state.counter)).subscribe((value) => {
        console.log(value)
        this.counter = value;
      });
    }

    onIncrement() {
      this.store.dispatch(increment());
    }

    onDecrement() {
      this.store.dispatch(decrement());
    }
  }

Reducer

import { createReducer, on } from '@ngrx/store';
import { increment, decrement } from './app.actions';
import { initialState } from './app.state';

export const appReducer = createReducer(
  initialState,
  on(increment, (state) => {
    return { ...state, counter: state.counter + 1 };
  }),
  on(decrement, (state) => {
    return { ...state, counter: state.counter - 1 };
  })
);

App module

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { EffectsModule } from '@ngrx/effects';
import { StoreModule } from '@ngrx/store';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CounterComponent } from './counter.component';
import { appReducer } from './state/app.reducer';

@NgModule({
  declarations: [
    AppComponent,
    CounterComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    StoreModule.forRoot({ counter: appReducer }),
    EffectsModule.forRoot([])
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

state

export interface AppState {
  counter: number;
}

export const initialState: AppState = {
  counter: 0
};

Actions

import { createAction } from '@ngrx/store';

export const increment = createAction('[Counter] Increment');
export const decrement = createAction('[Counter] Decrement');

Upvotes: 1

Views: 61

Answers (1)

Jamil
Jamil

Reputation: 193

In app.module change:

StoreModule.forRoot({ counter: appReducer }),

to:

StoreModule.forRoot({ appState: appReducer }),

and in the counter component change the selector to:

  this.store.pipe(select((state: AppState) => state.appState.counter)).subscribe((value) => {

BUT: the best practice is to create a Selector

https://v7.ngrx.io/guide/store/selectors

Upvotes: 1

Related Questions