Created
March 26, 2019 12:46
-
-
Save vinicius91/f850d85d3cf980f0ea95e1a07d7153c3 to your computer and use it in GitHub Desktop.
Reducer Example @ngrx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { Component, OnInit } from '@angular/core'; | |
| import { Recipient } from './model'; | |
| import { GetRecipientStart } from './store'; | |
| import { | |
| recipientLoading, | |
| selectAllRecipient | |
| } from './store/recipient.selector'; | |
| import { Observable } from 'rxjs'; | |
| import { MatTableDataSource } from '@angular/material'; | |
| import { select, Store } from '@ngrx/store'; | |
| import { AppState } from 'src/app/reducers'; | |
| @Component({ | |
| selector: 'app-recipient', | |
| templateUrl: './recipient.component.html', | |
| styleUrls: ['./recipient.component.scss'] | |
| }) | |
| export class RecipientComponent implements OnInit { | |
| loading$: Observable<boolean>; | |
| recipients$: Observable<Recipient[]>; | |
| recipients: MatTableDataSource<Recipient>; | |
| constructor(private store: Store<AppState>) {} | |
| ngOnInit() { | |
| this.store.dispatch(new GetRecipientStart()); | |
| this.loading$ = this.store.pipe(select(recipientLoading)); | |
| this.recipients$ = this.store.pipe(select(selectAllRecipient)); | |
| this.recipients$.subscribe((data) => { | |
| this.recipients = new MatTableDataSource<Recipient>(data); | |
| }); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { Action } from '@ngrx/store'; | |
| import { Recipient } from '../model'; | |
| import { UserByEntity } from 'src/app/shared/model'; | |
| export enum RecipientActionTypes { | |
| GetRecipientStart = '[Recipient List Page] Get Recipient start', | |
| GetRecipientSuccess = '[Recipient API] Get Recipient success', | |
| GetRecipientError = '[Recipient API] Get Recipient error', | |
| FindRecipientStart = '[Recipient Detail Page] Find Recipient start', | |
| FindRecipientSuccess = '[Recipient API] Find Recipient success', | |
| FindRecipientError = '[Recipient API] Find Recipient error', | |
| GetUserByEntityListStart = '[Recipient Detail Page] Get user by entity Start', | |
| GetUserByEntityListSuccess = '[Recipient Detail Page] Get user by entity Success', | |
| GetUserByEntityListError = '[Recipient Detail Page] Get user by entity Error', | |
| AlterUserSendEmailStatusStart = '[Recipient Users Page] Alter user send email status Start', | |
| AlterUserSendEmailStatusSuccess = '[Recipient Users Page] Alter user send email status Success', | |
| AlterUserSendEmailStatusError = '[Recipient Users Page] Alter user send email status Error' | |
| } | |
| export class GetRecipientStart implements Action { | |
| readonly type = RecipientActionTypes.GetRecipientStart; | |
| } | |
| export class GetRecipientSuccess implements Action { | |
| readonly type = RecipientActionTypes.GetRecipientSuccess; | |
| constructor(public payload: { recipients: Recipient[] }) {} | |
| } | |
| export class GetRecipientError implements Action { | |
| readonly type = RecipientActionTypes.GetRecipientError; | |
| } | |
| export class FindRecipientStart implements Action { | |
| readonly type = RecipientActionTypes.FindRecipientStart; | |
| constructor(public payload: { recipientId: number }) {} | |
| } | |
| export class FindRecipientSuccess implements Action { | |
| readonly type = RecipientActionTypes.FindRecipientSuccess; | |
| constructor(public payload: { recipient: Recipient }) {} | |
| } | |
| export class FindRecipientError implements Action { | |
| readonly type = RecipientActionTypes.FindRecipientError; | |
| } | |
| export class GetUserByEntityListStart implements Action { | |
| readonly type = RecipientActionTypes.GetUserByEntityListStart; | |
| constructor(public payload: { entityId: number }) {} | |
| } | |
| export class GetUserByEntityListSuccess implements Action { | |
| readonly type = RecipientActionTypes.GetUserByEntityListSuccess; | |
| constructor(public payload: { usersByEntity: UserByEntity[] }) {} | |
| } | |
| export class GetScheduleEmailListError implements Action { | |
| readonly type = RecipientActionTypes.GetUserByEntityListError; | |
| } | |
| export class AlterUserSendEmailStatusStart implements Action { | |
| readonly type = RecipientActionTypes.AlterUserSendEmailStatusStart; | |
| constructor(public payload: { userId: number; include: boolean }) {} | |
| } | |
| export class AlterUserSendEmailStatusSuccess implements Action { | |
| readonly type = RecipientActionTypes.AlterUserSendEmailStatusSuccess; | |
| constructor(public payload: { userId: number; success: boolean }) {} | |
| } | |
| export class AlterUserSendEmailStatusError implements Action { | |
| readonly type = RecipientActionTypes.AlterUserSendEmailStatusError; | |
| } | |
| export type RecipientActions = | |
| | GetRecipientStart | |
| | GetRecipientSuccess | |
| | GetRecipientError | |
| | FindRecipientStart | |
| | FindRecipientSuccess | |
| | FindRecipientError | |
| | GetUserByEntityListStart | |
| | GetUserByEntityListSuccess | |
| | GetScheduleEmailListError | |
| | AlterUserSendEmailStatusStart | |
| | AlterUserSendEmailStatusSuccess | |
| | AlterUserSendEmailStatusError; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class="row"> | |
| <div class="col-lg-12 col-md-12 col-sm-12"> | |
| <app-recipient-table | |
| ><div class="spinner-container" *ngIf="(loading$ | async)"> | |
| <app-truck-loading></app-truck-loading></div | |
| ></app-recipient-table> | |
| </div> | |
| <app-modal baseUrl="/settings/recipient"></app-modal> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { Injectable } from '@angular/core'; | |
| import { Actions, Effect, ofType } from '@ngrx/effects'; | |
| import { mergeMap, map } from 'rxjs/operators'; | |
| import { RecipientService } from './side-effects'; | |
| import { | |
| GetRecipientStart, | |
| RecipientActionTypes, | |
| GetRecipientSuccess, | |
| GetUserByEntityListStart, | |
| GetUserByEntityListSuccess, | |
| AlterUserSendEmailStatusStart, | |
| AlterUserSendEmailStatusSuccess, | |
| AlterUserSendEmailStatusError | |
| } from './recipient.actions'; | |
| @Injectable() | |
| export class RecipientEffects { | |
| constructor(private actions$: Actions, private service: RecipientService) {} | |
| @Effect() | |
| getAll$ = this.actions$.pipe( | |
| ofType<GetRecipientStart>(RecipientActionTypes.GetRecipientStart), | |
| mergeMap((action) => this.service.findAllRecipients()), | |
| map((response) => { | |
| return new GetRecipientSuccess({ | |
| recipients: response.results | |
| }); | |
| }) | |
| ); | |
| @Effect() | |
| getAllUsersByEntity$ = this.actions$.pipe( | |
| ofType<GetUserByEntityListStart>( | |
| RecipientActionTypes.GetUserByEntityListStart | |
| ), | |
| mergeMap((action) => | |
| this.service.findUsersByEntity(action.payload.entityId) | |
| ), | |
| map((usersByEntity) => { | |
| return new GetUserByEntityListSuccess({ | |
| usersByEntity | |
| }); | |
| }) | |
| ); | |
| @Effect() | |
| alterUserSendEmailStatus$ = this.actions$.pipe( | |
| ofType<AlterUserSendEmailStatusStart>( | |
| RecipientActionTypes.AlterUserSendEmailStatusStart | |
| ), | |
| mergeMap((action) => | |
| this.service.alterUserSendEmailStatus( | |
| action.payload.userId, | |
| action.payload.include | |
| ) | |
| ), | |
| map(({ userId, success }) => { | |
| if (success) { | |
| return new AlterUserSendEmailStatusSuccess({ | |
| userId, | |
| success | |
| }); | |
| } else { | |
| return new AlterUserSendEmailStatusError(); | |
| } | |
| }) | |
| ); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity'; | |
| import { Recipient } from '../model'; | |
| import { RecipientActions, RecipientActionTypes } from './recipient.actions'; | |
| import { UserByEntity } from 'src/app/shared/model'; | |
| export interface RecipientState extends EntityState<Recipient> { | |
| loading: boolean; | |
| loadingEmails: boolean; | |
| usersByEntity: UserByEntity[]; | |
| } | |
| export const adapter: EntityAdapter<Recipient> = createEntityAdapter< | |
| Recipient | |
| >(); | |
| export const initialRecipientState: RecipientState = adapter.getInitialState({ | |
| loading: false, | |
| loadingEmails: false, | |
| usersByEntity: [] | |
| }); | |
| export function recipientReducer( | |
| state = initialRecipientState, | |
| action: RecipientActions | |
| ): RecipientState { | |
| switch (action.type) { | |
| case RecipientActionTypes.GetRecipientStart: | |
| return { ...state, loading: true }; | |
| case RecipientActionTypes.GetUserByEntityListStart: | |
| return { ...state, loadingEmails: true }; | |
| case RecipientActionTypes.GetRecipientSuccess: | |
| return adapter.addAll(action.payload.recipients, { | |
| ...state, | |
| loading: false | |
| }); | |
| case RecipientActionTypes.GetUserByEntityListSuccess: | |
| return { | |
| ...state, | |
| usersByEntity: action.payload.usersByEntity, | |
| loadingEmails: false | |
| }; | |
| case RecipientActionTypes.AlterUserSendEmailStatusStart: | |
| return { ...state, loadingEmails: true }; | |
| case RecipientActionTypes.AlterUserSendEmailStatusSuccess: | |
| const user = state.usersByEntity.find( | |
| (x) => x.user.id === action.payload.userId | |
| ); | |
| const notificationTypes = | |
| user.notificationTypes.length > 0 ? [] : ['SCHEDULE']; | |
| const usersByEntity = [ | |
| ...state.usersByEntity.filter( | |
| (x) => x.user.id !== action.payload.userId | |
| ), | |
| { ...user, notificationTypes } | |
| ]; | |
| return { | |
| ...state, | |
| loadingEmails: false, | |
| usersByEntity | |
| }; | |
| default: | |
| return state; | |
| } | |
| } | |
| export const { | |
| selectAll, | |
| selectEntities, | |
| selectIds, | |
| selectTotal | |
| } = adapter.getSelectors(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { createFeatureSelector, createSelector } from '@ngrx/store'; | |
| import * as fromRecipient from './recipient.reducer'; | |
| import { PageQuery } from 'src/app/shared/model'; | |
| export const selectRecipientState = createFeatureSelector< | |
| fromRecipient.RecipientState | |
| >('recipient'); | |
| export const selectRecipientById = (recipientId: number) => | |
| createSelector( | |
| selectRecipientState, | |
| (recipientState) => recipientState.entities[recipientId] | |
| ); | |
| export const selectAllRecipient = createSelector( | |
| selectRecipientState, | |
| fromRecipient.selectAll | |
| ); | |
| export const recipientLoading = createSelector( | |
| selectRecipientState, | |
| (recipientState) => recipientState.loading | |
| ); | |
| export const selectRecipientPage = (page: PageQuery) => | |
| createSelector( | |
| selectAllRecipient, | |
| (allRecipients) => { | |
| const start = page.pageIndex * page.pageSize, | |
| end = start + page.pageSize; | |
| return allRecipients.slice(start, end); | |
| } | |
| ); | |
| export const selectRecipientsTotal = createSelector( | |
| selectAllRecipient, | |
| (recipients) => recipients.length | |
| ); | |
| export const emailsToSendLoading = createSelector( | |
| selectRecipientState, | |
| (recipientState) => recipientState.loadingEmails | |
| ); | |
| export const selectUsersByEntity = createSelector( | |
| selectRecipientState, | |
| (recipientState) => recipientState.usersByEntity | |
| ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { Injectable } from '@angular/core'; | |
| import { HttpClient, HttpHeaders } from '@angular/common/http'; | |
| import { Observable } from 'rxjs'; | |
| import { map, catchError } from 'rxjs/operators'; | |
| import { environment } from 'src/environments/environment'; | |
| import { Page } from 'src/app/shared/model/page'; | |
| import { AppState } from 'src/app/reducers'; | |
| import { Store } from '@ngrx/store'; | |
| import { Recipient } from '../../model'; | |
| import { UserByEntity } from 'src/app/shared/model'; | |
| import { NotificationService, NotificationType } from 'src/app/core/services'; | |
| import { NotificationOrigin } from 'src/app/core/services/notification-origin.enum'; | |
| import { NotificationAlignment } from 'src/app/core/services/notification-alignment.enum'; | |
| @Injectable() | |
| export class RecipientService { | |
| private httpOptions = { | |
| headers: new HttpHeaders({ | |
| 'Content-Type': 'text/plain', | |
| Accept: 'text/plain' | |
| }) | |
| }; | |
| API_URL: string = environment.API_URL; | |
| constructor( | |
| private http: HttpClient, | |
| private notification: NotificationService | |
| ) {} | |
| findAllRecipients(): Observable<Page<Recipient>> { | |
| return this.http | |
| .get<any>(`${this.API_URL}/recipient?limit=100`, this.httpOptions) | |
| .pipe( | |
| catchError((error) => { | |
| console.error(error); | |
| this.notification.notify( | |
| NotificationOrigin.TOP, | |
| NotificationAlignment.RIGHT, | |
| NotificationType.DANGER, | |
| 'Ocorreu um erro em sua solicitação' | |
| ); | |
| return []; | |
| }), | |
| map((res) => res) | |
| ); | |
| } | |
| findUsersByEntity(entityId: number): Observable<UserByEntity[]> { | |
| return this.http | |
| .get<UserByEntity[]>( | |
| `${ | |
| this.API_URL | |
| }/user-by-entity-id?entityId=${entityId}&entityType=RECIPIENT`, | |
| this.httpOptions | |
| ) | |
| .pipe( | |
| catchError((error) => { | |
| console.error(error); | |
| this.notification.notify( | |
| NotificationOrigin.TOP, | |
| NotificationAlignment.RIGHT, | |
| NotificationType.DANGER, | |
| 'Ocorreu um erro em sua solicitação' | |
| ); | |
| return []; | |
| }), | |
| map((res) => res) | |
| ); | |
| } | |
| alterUserSendEmailStatus( | |
| userId: number, | |
| include: boolean | |
| ): Observable<{ userId: number; success: boolean }> { | |
| const body = include ? ['SCHEDULE'] : []; | |
| return this.http | |
| .post<boolean>( | |
| `${this.API_URL}/user/${userId}/notification`, | |
| body, | |
| this.httpOptions | |
| ) | |
| .pipe( | |
| catchError((error) => { | |
| console.error(error); | |
| this.notification.notify( | |
| NotificationOrigin.TOP, | |
| NotificationAlignment.RIGHT, | |
| NotificationType.DANGER, | |
| 'Ocorreu um erro em sua solicitação' | |
| ); | |
| return []; | |
| }), | |
| map((success) => { | |
| return { userId, success }; | |
| }) | |
| ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment