From 8d3613afbd6c5b6766ab83ee0af9b15f57763be0 Mon Sep 17 00:00:00 2001 From: Hugo BAYOUD <hugo.bayoud@etu.uca.fr> Date: Thu, 25 Mar 2021 08:59:19 +0100 Subject: [PATCH] create action, reducer, effect and selector for fetching bars need to handle error in FetchBars effect --- src/app/components/bars/bars.component.html | 5 ++- src/app/components/bars/bars.component.ts | 20 ++++++++++-- .../photos/shared/store/photos.reducers.ts | 2 +- .../photos/shared/store/photos.selectors.ts | 2 ++ src/app/share/models/bar.model.ts | 7 ++++ src/app/share/services/bars.service.ts | 10 +++++- src/app/share/store/actions/bars.actions.ts | 18 +++++++++++ src/app/share/store/effects/bars.effects.ts | 32 +++++++++++++++++++ src/app/share/store/index.ts | 5 ++- src/app/share/store/reducers/bars.reducers.ts | 28 ++++++++++++++++ .../share/store/selectors/bars.selectors.ts | 8 +++++ 11 files changed, 130 insertions(+), 7 deletions(-) create mode 100644 src/app/share/models/bar.model.ts create mode 100644 src/app/share/store/actions/bars.actions.ts create mode 100644 src/app/share/store/effects/bars.effects.ts create mode 100644 src/app/share/store/reducers/bars.reducers.ts create mode 100644 src/app/share/store/selectors/bars.selectors.ts diff --git a/src/app/components/bars/bars.component.html b/src/app/components/bars/bars.component.html index 6c4e88db..c2a509b5 100644 --- a/src/app/components/bars/bars.component.html +++ b/src/app/components/bars/bars.component.html @@ -2,4 +2,7 @@ <p> <button mat-raised-button routerLink="/profile" color="primary">profile</button> <button mat-raised-button routerLink="/photos" color="accent">photos</button> -</p> \ No newline at end of file +</p> + <ul> + <li *ngFor="let bar of bars">{{ bar.shortname }} - {{ bar.longname }}</li> +</ul> \ No newline at end of file diff --git a/src/app/components/bars/bars.component.ts b/src/app/components/bars/bars.component.ts index 9046c8da..361e844d 100644 --- a/src/app/components/bars/bars.component.ts +++ b/src/app/components/bars/bars.component.ts @@ -1,4 +1,8 @@ import { Component, OnInit } from '@angular/core'; +import { Observable } from 'rxjs'; +import { catchError, map } from 'rxjs/operators'; +import { Bar } from '../../share/models/bar.model'; +import { BarsService } from '../../share/services/bars.service'; @Component({ selector: 'app-bars', @@ -6,9 +10,19 @@ import { Component, OnInit } from '@angular/core'; styleUrls: ['./bars.component.css'] }) export class BarsComponent implements OnInit { + public bars: Bar[]; - constructor() {} - - ngOnInit(): void {} + constructor(private barsService: BarsService) {} + ngOnInit(): void { + this.barsService.getAllBars().pipe( + map((bars: Bar[]) => { + console.log(bars); + this.bars = bars; + }), + catchError((err) => { + console.log(err); + }) + ); + } } diff --git a/src/app/photos/shared/store/photos.reducers.ts b/src/app/photos/shared/store/photos.reducers.ts index 629382d6..b775b55c 100644 --- a/src/app/photos/shared/store/photos.reducers.ts +++ b/src/app/photos/shared/store/photos.reducers.ts @@ -3,7 +3,7 @@ import { Photo } from "../models/photo.model"; export interface PhotosState { photos: Photo[]; - filter:string; + filter: string; } const defaultPhotoState = { diff --git a/src/app/photos/shared/store/photos.selectors.ts b/src/app/photos/shared/store/photos.selectors.ts index d711f16c..c68d8b49 100644 --- a/src/app/photos/shared/store/photos.selectors.ts +++ b/src/app/photos/shared/store/photos.selectors.ts @@ -2,5 +2,7 @@ import { createFeatureSelector, createSelector } from "@ngrx/store"; import { PhotosState } from "./photos.reducers"; export const baseSelector = createFeatureSelector('photos'); + export const filterPhotosSelector = createSelector(baseSelector, (photosState: PhotosState) => photosState?.filter); + export const photosSelector = createSelector(baseSelector, (photosState: PhotosState) => photosState?.photos); \ No newline at end of file diff --git a/src/app/share/models/bar.model.ts b/src/app/share/models/bar.model.ts new file mode 100644 index 00000000..b4d59963 --- /dev/null +++ b/src/app/share/models/bar.model.ts @@ -0,0 +1,7 @@ +export interface Bar { + shortname: string; + longname: string; + description: string; + adress: string; + logo: string; +} \ No newline at end of file diff --git a/src/app/share/services/bars.service.ts b/src/app/share/services/bars.service.ts index 74ff23e2..3b477eb1 100644 --- a/src/app/share/services/bars.service.ts +++ b/src/app/share/services/bars.service.ts @@ -1,9 +1,17 @@ +import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { Bar } from '../models/bar.model'; @Injectable({ providedIn: 'root' }) export class BarsService { - constructor() { } + constructor(private http: HttpClient) {} + + // authInterceptor add the token in the HTTP request + public getAllBars(): Observable<Bar[]> { + return this.http.get<Bar[]>('/api/bars'); + } } diff --git a/src/app/share/store/actions/bars.actions.ts b/src/app/share/store/actions/bars.actions.ts new file mode 100644 index 00000000..4ed21b9c --- /dev/null +++ b/src/app/share/store/actions/bars.actions.ts @@ -0,0 +1,18 @@ +import { Action } from "@ngrx/store"; +import { Bar } from "../../models/bar.model"; + +export enum BarsActionsTypes { + FETCH_BARS = '[bars/api] fetch all bars', + FETCH_BARS_SUCCESS = '[bars/api] fetch bars success' +} + +export class FetchBars implements Action { + readonly type = BarsActionsTypes.FETCH_BARS; +} + +export class FetchBarsSuccess implements Action { + readonly type = BarsActionsTypes.FETCH_BARS_SUCCESS; + constructor(public payload: Bar[]) {} +} + +export type BarsAction = FetchBars | FetchBarsSuccess; \ No newline at end of file diff --git a/src/app/share/store/effects/bars.effects.ts b/src/app/share/store/effects/bars.effects.ts new file mode 100644 index 00000000..7205155c --- /dev/null +++ b/src/app/share/store/effects/bars.effects.ts @@ -0,0 +1,32 @@ +import { Injectable } from "@angular/core"; +import { Actions, Effect, ofType } from "@ngrx/effects"; +import { Store } from "@ngrx/store"; +import { catchError, map, switchMap } from "rxjs/operators"; + +import { State } from "../../../share/store"; +import { Bar } from "../../models/bar.model"; +import { BarsService } from "../../services/bars.service"; +import { BarsActionsTypes, FetchBarsSuccess } from "../actions/bars.actions"; + +@Injectable() +export class BarsEffect { + constructor( + private actions$: Actions, + private store: Store<State>, + private barssService: BarsService + ) {} + + @Effect() + FetchBars$ = this.actions$.pipe( + ofType(BarsActionsTypes.FETCH_BARS), + switchMap(() => { + return this.barssService.getAllBars(); + }), + map((bars: Bar[]) => { + return new FetchBarsSuccess(bars); + }), + // catchError((err) => { + // console.log(err); + // }) + ); +} \ No newline at end of file diff --git a/src/app/share/store/index.ts b/src/app/share/store/index.ts index 89f69ed9..392c1193 100644 --- a/src/app/share/store/index.ts +++ b/src/app/share/store/index.ts @@ -1,10 +1,13 @@ import { ActionReducerMap } from "@ngrx/store"; import { authReducer, AuthState } from "./reducers/auth.reducers"; +import { barsReducer, BarsState } from "./reducers/bars.reducers"; export interface State { auth: AuthState; + bars: BarsState; } export const reducersMap: ActionReducerMap<State> = { - auth: authReducer + auth: authReducer, + bars: barsReducer }; \ No newline at end of file diff --git a/src/app/share/store/reducers/bars.reducers.ts b/src/app/share/store/reducers/bars.reducers.ts new file mode 100644 index 00000000..7c29c885 --- /dev/null +++ b/src/app/share/store/reducers/bars.reducers.ts @@ -0,0 +1,28 @@ +import { PhotosAction, PhotosActionsTypes } from "./photos.actions"; +import { Photo } from "../models/photo.model"; +import { Bar } from "../../models/bar.model"; +import { BarsAction, BarsActionsTypes } from "../actions/bars.actions"; + +export interface BarsState { + bars: Bar[]; + currentBar: Bar; +} + +const defaultBarState = { + bars: [], + currentBar: null +} + +export function barsReducer(state: BarsState = defaultBarState, action: BarsAction): BarsState { + switch (action.type) { + + case BarsActionsTypes.FETCH_BARS_SUCCESS: { + return { + ...state, + bars: action.payload + }; + } + } + + return state; +} \ No newline at end of file diff --git a/src/app/share/store/selectors/bars.selectors.ts b/src/app/share/store/selectors/bars.selectors.ts new file mode 100644 index 00000000..0e8b1480 --- /dev/null +++ b/src/app/share/store/selectors/bars.selectors.ts @@ -0,0 +1,8 @@ +import { createFeatureSelector, createSelector } from "@ngrx/store"; +import { BarsState } from "../reducers/bars.reducers"; + +export const baseSelector = createFeatureSelector('bars'); + +export const allBarsSelector = createSelector(baseSelector, (barsState: BarsState) => barsState?.bars); + +export const currentBarSelector = createSelector(baseSelector, (barsState: BarsState) => barsState?.currentBar); \ No newline at end of file -- GitLab