I created this example table of NgRx built with Angular and Material.
Let's walk through a simple example of how NgRx can be used to manage the state of a counter in an Angular application.
1. Setup: First, make sure you have Angular CLI installed. You can create a new Angular application using the following command:
ng new ngrx-counter-app
2. Install NgRx: Navigate to the project directory and install the necessary NgRx packages:
cd ngrx-counter-app
npm install @ngrx/store @ngrx/effects @ngrx/entity @ngrx/store-devtools
3. Define Actions: Create a file named `counter.actions.ts` in the `src/app` directory to define the actions for your counter:
// counter.actions.ts
import { createAction } from '@ngrx/store';
export const increment = createAction('[Counter] Increment');
export const decrement = createAction('[Counter] Decrement');
export const reset = createAction('[Counter] Reset');
4. Define Reducer: Create a file named `counter.reducer.ts` in the `src/app` directory to define the reducer for your counter:
// counter.reducer.ts
import { createReducer, on } from '@ngrx/store';
import { increment, decrement, reset } from './counter.actions';
export const initialState = 0;
export const counterReducer = createReducer(
initialState,
on(increment, (state) => state + 1),
on(decrement, (state) => state - 1),
on(reset, () => initialState)
);
5. Define Effects: Create a file named `counter.effects.ts` in the `src/app` directory to define effects for your counter (though we won't use any asynchronous operations in this simple example):
// counter.effects.ts
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { EMPTY } from 'rxjs';
import { catchError, map, mergeMap } from 'rxjs/operators';
@Injectable()
export class CounterEffects {
constructor(private actions$: Actions) {}
// No effects defined in this simple example
}
6. Setup Store: Update the `src/app/app.module.ts` file to configure the NgRx store and effects:
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import { AppComponent } from './app.component';
import { counterReducer } from './counter.reducer';
import { CounterEffects } from './counter.effects';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
StoreModule.forRoot({ count: counterReducer }),
EffectsModule.forRoot([CounterEffects])
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
7. Create Components: Create components to interact with the counter state. For this example, create a simple counter component that displays the counter value and buttons to increment, decrement, and reset the counter.
// counter.component.ts
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { increment, decrement, reset } from './counter.actions';
@Component({
selector: 'app-counter',
template: `
<div>
<h2>Counter: {{ count$ | async }}</h2>
<button (click)="increment()">Increment</button>
<button (click)="decrement()">Decrement</button>
<button (click)="reset()">Reset</button>
</div>
`,
})
export class CounterComponent {
count$ = this.store.select(state => state.count);
constructor(private store: Store) {}
increment() {
this.store.dispatch(increment());
}
decrement() {
this.store.dispatch(decrement());
}
reset() {
this.store.dispatch(reset());
}
}
8. Use Component: Add the `CounterComponent` to your `app.component.html` file:
<!-- app.component.html -->
<app-counter></app-counter>
9. Run the Application: Start the development server and see the NgRx-powered counter in action:
ng serve
Navigate to `http://localhost:4200` in your web browser to see the counter component with increment, decrement, and reset buttons. The state management for the counter is handled by NgRx.
Remember, this is a simplified example. In a real-world application, you might have more complex state, multiple components, and asynchronous operations, all of which NgRx can help you manage in a structured and predictable way.