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