I'm building a 'hello world' app using NGRX, but the state of my app keeps the initial value even when I'm triggering actions that should change it.
This is my app.module:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { StoreModule } from '@ngrx/store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { counterReducer } from './contador.reducer';
import { environment } from 'src/environments/environment';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
StoreModule.forRoot({ counter: counterReducer }),
StoreDevtoolsModule.instrument({
maxAge: 25,
logOnly: environment.production,
})
],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.ts:
import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { decrement, increment } from './contador/contador.actions';
interface AppState {
counter: number
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
public counter!: number;
constructor(private store: Store<AppState>) {
this.store.subscribe(state => {
console.log('state', state)
this.counter = state.counter;
})
}
ngOnInit() { }
inc() {
this.store.dispatch(increment())
}
dec() {
this.store.dispatch(decrement())
}
}
app.component.html:
<div class="container-fluid text-center">
<div class="row">
<div class="col pt-5">
<h1>Counter</h1>
<h2>{{counter}}</h2>
</div>
</div>
<button (click)="inc()" class="btn btn-primary pr-5">increment</button>
<button (click)="dec()" class="btn btn-primary pr-5">decrement</button>
</div>
counter.reducer.ts:
import { decrement, increment } from './contador/contador.actions';
import { Action, createReducer, on } from "@ngrx/store";
export const initialState = 20;
const _counterReducer = createReducer(initialState,
on(increment => initialState + 1),
on(decrement => initialState - 1)
)
export function counterReducer(initialState: number | undefined, actions: Action) {
return _counterReducer(initialState, actions)
}
contador.actions.ts
import { createAction } from "@ngrx/store"
export const increment = createAction('[counter] increment')
export const decrement = createAction('[counter] decrement')
The only thing I'm seeing is that in the reducer, the increment
and decrement
imports are not being used in the on() methods as they are unused imports.
I always get the initialValue = 0
, no matter if I click the increment or decrement buttons.
The on
cases in you reducer are not defined correctly.
The first argument is the action, second argument is a function which takes the existing state, then returns a modified version of it according to the specified action.
const _counterReducer = createReducer(initialState,
on(increment, state => state + 1),
on(decrement, state => state - 1)
);