Adrian Faciu
Principal software engineer. Focused on front-end. Learning something new each day. Building things at WeVideo.
github.com/
ng-training/
ngrx-workshop
+
+
const incrementAction = { type: 'INCREMENT' }
const addAction = {
type: 'ADD',
value: 4,
}
interface Action {
type: string;
}
import { createAction } from '@ngrx/store';
export const increment = createAction('Increment');
import { createAction, props } from '@ngrx/store';
export const add = createAction(
'[Calculator Page] Add',
props<{ value: number }>()
);
export function reducer(
state = initialState,
action: Action
) {
if (action.type === 'Increment') {
return { count: state.count++ }
}
return state;
}
export function reducer(
state = initialState,
action: Action
) {
switch (action.type) {
case 'Increment': {
return { count: state.count++ }
}
case 'Decrement': {
return { count: state.count-- }
}
default: {
return state;
}
}
}
import { createAction, createReducer, on }
from '@ngrx/store';
export const increment = createAction('Increment');
export const decrement = createAction('Decrement');
export const reducer = createReducer(
initialState,
on(increment, (state) => ({ count: state.count++ })),
on(decrement, (state) => ({ count: state.count-- })),
);
import { StoreModule } from '@ngrx/store';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
StoreModule.forRoot({
user: userReducer,
count: countReducer,
}),
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
import { StoreModule } from '@ngrx/store';
import { StoreDevtoolsModule }
from '@ngrx/store-devtools';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
StoreModule.forRoot(reducers),
StoreDevtoolsModule.instrument({
maxAge: 25,
logOnly: environment.production,
}),
],
bootstrap: [AppComponent],
})
export class AppModule {}
Pure functions, used to get slices of state
import { createSelector } from '@ngrx/store';
interface AppState {
user: UserState;
}
interface UserState {
username?: string;
}
const getUserState = (state: GlobalState)
=> state.user;
const getUserName = createSelector(
getUserState,
state => state.username
);
Connects the Angular router to the Store
import { StoreRouterConnectingModule, routerReducer }
from '@ngrx/router-store';
import { AppComponent } from './app.component';
@NgModule({
imports: [
BrowserModule,
StoreModule.forRoot({
router: routerReducer,
}),
StoreRouterConnectingModule.forRoot(),
],
bootstrap: [AppComponent],
})
export class AppModule {}
@NgModule({
imports: [
StoreModule.forRoot(reducers, {
runtimeChecks: {
strictStateImmutability: true,
strictActionImmutability: true,
strictStateSerializability: true,
strictActionSerializability: true,
},
}),
],
})
export class AppModule {}
Scaffolding library for Angular applications using NgRx libraries
npm install @ngrx/schematics -D
ng generate @ngrx/schematics:store State
--root --module app.module.ts
ng generate @ngrx/schematics:effect App
--root --module app.module.ts
ng generate @ngrx/schematics:action user
ng config cli.defaultCollection @ngrx/schematics
ng generate action user
export function debug(reducer: ActionReducer<any>){
return function(state, action) {
console.log('state', state);
console.log('action', action);
return reducer(state, action);
};
}
export const metaReducers: MetaReducer<any>[] = [debug];
@NgModule({
imports: [
StoreModule.forRoot(reducers, { metaReducers })
],
})
export class AppModule {}
interface EntityState<V> {
ids: string[] | number[];
entities: { [id: string | id: number]: V };
}
interface State extends EntityState<User> {
selectedUserId: number | null;
}
const adapter: EntityAdapter<User>
= createEntityAdapter<User>();
Use the 'real' Store
export const selectTotal = createSelector(
selectSumEvenNums,
selectSumOddNums,
(evenSum, oddSum) => evenSum + oddSum
);
describe('My Selectors', () => {
it('should calc selectTotal', () => {
expect(selectTotal.projector(2, 3)).toBe(5);
});
});
By Adrian Faciu
The main part of the NgRx workshop.
Principal software engineer. Focused on front-end. Learning something new each day. Building things at WeVideo.