Categories
Uncategorized

State Management in Angular 5.x using ngrx

state management

job-state.ts

Let us assume we have a job object with the following properties.

export interface JobState {
    id: number;
    title: string;
    company: string;
    city: string;
    state: string;
    zip: number;
}

job-state.ts

Let us create actions classes by implementing the Action interface and then export them with type All, to avoid type mismatch errors.

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

import {JobState} from './job-state';

export const ADDJOB = 'ADDJOB';
export const GETJOB = 'GETJOB';

export class AddJobPost implements Action {
    readonly type = ADDJOB;

    constructor(public payload: JobState) {
    }
}

export class GetJobPost implements Action {
    readonly type = GETJOB;
}

export type All = AddJobPost | GetJobPost;

job.reducer.ts

Now we need to create the reducer which maps the actions to the correct state.

import * as PostActions from './job-actions';
import {JobState} from './job-state';

export type Action = PostActions.All;

const emptyJobState = {
    id: null,
    title: null,
    company: null,
    city: null,
    state: null,
    zip: null,
};

const newState = (state, newData) => {
    return Object.assign({}, state, newData);
};

export function jobReducer(state: JobState = emptyJobState, action: Action) {
    switch (action.type) {
        case PostActions.ADDJOB: {
            return newState(state, action.payload);
        }
        case PostActions.GETJOB: {
            return Object.assign({}, state);
        }
        default: {
            return Object.assign({}, state);
        }
    }
}

app.component.ts

Now we need to include the reducer in the component, that we can to make use of this functionality. Here let us consider app.component.ts

import {Component, OnInit} from '@angular/core';
import {Store} from '@ngrx/store';

import * as PostActions from '../reducers/job-actions';
import {JobState} from './job-state';
import {JobStateInterface} from './job-state.interface';

@Component({
    selector: 'app',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
    job: Observable;
    jobs: JobState[];

    constructor(private store: Store) {
        this.job = store.select('job');
    }

 
    setJob(obj: JobState): void {
        this.store.dispatch(new PostActions.AddJobPost(obj));
    }

}

job-state.interface.ts

We need to define the interface that the store uses to retrieve the state.

import {JobState} from './job-state';

export interface JobStateInterface {
    job: JobState;
}

app.module.ts

Finally we need to add the reducer to the app.module.ts. There is a nice chrome plugin called redux dev-tools</ that comes in handy to view the current state of the application and manipulate it. You need add the StoreDevtoolsModule line as shown below, after installing and enabling the above plugin in your code.

// ...
import {job} from 'job.reducer';

@NgModule({
// ...

 imports: [
        BrowserModule,
        AppRoutingModule,
        FormsModule,
        HttpClientModule,
        StoreModule.forRoot({login: loginReducer, job: jobReducer}),
        StoreDevtoolsModule.instrument({
            maxAge: 25
        }),

// ...
})

// ...