From 14484d32be51d18537796fcac15b15253b22bcfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Romaszkin?= Date: Fri, 6 Nov 2020 22:24:15 +0100 Subject: [PATCH 1/7] NgRx init --- frontend/package-lock.json | 24 ++++++++++++++++++++++++ frontend/package.json | 3 +++ frontend/src/app/app.module.ts | 9 +++++++++ frontend/src/app/reducers/index.ts | 25 +++++++++++++++++++++++++ 4 files changed, 61 insertions(+) create mode 100644 frontend/src/app/reducers/index.ts diff --git a/frontend/package-lock.json b/frontend/package-lock.json index f506200..aaa31fd 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -2921,6 +2921,30 @@ "intersection-observer": "0.7.0" } }, + "@ngrx/effects": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-10.0.1.tgz", + "integrity": "sha512-pw0hRQNlyBBRHH1NRWl3TF+RtEAS4XOSnoTHPtQ84Ib/bEribvexsdEq3k6yLWvR3tLTudb5J6SYwYawcM6omA==", + "requires": { + "tslib": "^2.0.0" + } + }, + "@ngrx/store": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-10.0.1.tgz", + "integrity": "sha512-ZbPvhp/tRYnS3jZ28mDOX2LH3jfySXT0uv8ffIboM/o9QxBGHpAJyBct2zkpy4duYBc3i/sIbRn+CEpAjLXjHw==", + "requires": { + "tslib": "^2.0.0" + } + }, + "@ngrx/store-devtools": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@ngrx/store-devtools/-/store-devtools-10.0.1.tgz", + "integrity": "sha512-kwgF1yjjVn0FER+AG83OLCYSMuX4/E3L+DN4doSoZs4BNO9FdkYIIA4ul1nXT5d6SLiFFTmlufmbgc6HCF3pjQ==", + "requires": { + "tslib": "^2.0.0" + } + }, "@ngtools/webpack": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-10.0.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 57a76b3..408036e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,6 +19,9 @@ "@angular/router": "~10.0.0", "@nebular/eva-icons": "5.0.0", "@nebular/theme": "^5.0.0", + "@ngrx/effects": "^10.0.1", + "@ngrx/store": "^10.0.1", + "@ngrx/store-devtools": "^10.0.1", "@types/papaparse": "^5.0.3", "d3": "^5.16.0", "eva-icons": "^1.1.2", diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index a695b1d..5d1b6d3 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -18,6 +18,10 @@ import { import { FrontPageModule } from './front-page/front-page.module'; import { SharedDataService } from './_services/shared-data.service'; import { SidebarItemsService } from './_services/sidebar-items.service'; +import { StoreModule } from '@ngrx/store'; +import { reducers, metaReducers } from './reducers'; +import { StoreDevtoolsModule } from '@ngrx/store-devtools'; +import { EffectsModule } from '@ngrx/effects'; @NgModule({ declarations: [AppComponent], @@ -32,6 +36,11 @@ import { SidebarItemsService } from './_services/sidebar-items.service'; NbEvaIconsModule, FrontPageModule, NbToastrModule.forRoot(), + StoreModule.forRoot(reducers, { + metaReducers, + }), + StoreDevtoolsModule.instrument({ maxAge: 25 }), + EffectsModule.forRoot([]), ], bootstrap: [AppComponent], providers: [SharedDataService, NbSidebarService, SidebarItemsService], diff --git a/frontend/src/app/reducers/index.ts b/frontend/src/app/reducers/index.ts new file mode 100644 index 0000000..aad8dbf --- /dev/null +++ b/frontend/src/app/reducers/index.ts @@ -0,0 +1,25 @@ +import { + ActionReducer, + ActionReducerMap, + createFeatureSelector, + createSelector, + MetaReducer, +} from '@ngrx/store'; +import { environment } from '../../environments/environment'; + +export function debug(reducer: ActionReducer): ActionReducer { + return function (state, action) { + console.log('State: ', state); + console.log('Action', action); + + return reducer(state, action); + }; +} + +export interface State {} + +export const reducers: ActionReducerMap = {}; + +export const metaReducers: MetaReducer[] = !environment.production + ? [debug] + : []; From c53d8f550a0d56283a262e663104f9c990ae92d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Romaszkin?= Date: Sat, 7 Nov 2020 12:02:38 +0100 Subject: [PATCH 2/7] Add front page reducers and actions --- .../src/app/actions/front-page.actions.ts | 7 +++++ .../app/front-page/front-page.component.ts | 24 ++++++++++------- .../src/app/reducers/front-page.reducers.ts | 27 +++++++++++++++++++ frontend/src/app/reducers/index.ts | 9 ++++--- 4 files changed, 54 insertions(+), 13 deletions(-) create mode 100644 frontend/src/app/actions/front-page.actions.ts create mode 100644 frontend/src/app/reducers/front-page.reducers.ts diff --git a/frontend/src/app/actions/front-page.actions.ts b/frontend/src/app/actions/front-page.actions.ts new file mode 100644 index 0000000..55bee6e --- /dev/null +++ b/frontend/src/app/actions/front-page.actions.ts @@ -0,0 +1,7 @@ +import { createAction, props } from '@ngrx/store'; + +export const fetchFile = createAction( + '[FrontPage Component] Fetch File', + props<{ file: File }>() +); +export const sendFile = createAction('[FrontPage Component] Send File'); diff --git a/frontend/src/app/front-page/front-page.component.ts b/frontend/src/app/front-page/front-page.component.ts index 322c884..45e2b92 100644 --- a/frontend/src/app/front-page/front-page.component.ts +++ b/frontend/src/app/front-page/front-page.component.ts @@ -4,6 +4,9 @@ import { SendDataService } from '../_services/send-data.service'; import { SharedDataService } from '../_services/shared-data.service'; import { HttpErrorResponse } from '@angular/common/http'; import { NbToastrService } from '@nebular/theme'; +import { Store } from '@ngrx/store'; +import { State } from '../reducers/front-page.reducers'; +import { Observable } from 'rxjs'; @Component({ selector: 'app-front-page', @@ -11,18 +14,18 @@ import { NbToastrService } from '@nebular/theme'; styleUrls: ['./front-page.component.scss'], }) export class FrontPageComponent { - private file: File; - public fileName: string; - public isFileFetched: boolean; + // private file: File; + // public fileName: string; + // public isFileFetched: boolean; + file$: Observable; constructor( private sendDataService: SendDataService, private sharedDataService: SharedDataService, private router: Router, - private toastService: NbToastrService - ) { - this.isFileFetched = false; - } + private toastService: NbToastrService, + private store: Store<{ fileState: State }> + ) {} scrollTo(el: HTMLElement) { el.scrollIntoView({ behavior: 'smooth' }); @@ -38,9 +41,10 @@ export class FrontPageComponent { } fetchFile(event: any): void { - this.file = event.target.files[0]; - this.fileName = this.file.name; - this.isFileFetched = true; + this.store; + // this.file = event.target.files[0]; + // this.fileName = this.file.name; + // this.isFileFetched = true; } sendFile(event: any): void { diff --git a/frontend/src/app/reducers/front-page.reducers.ts b/frontend/src/app/reducers/front-page.reducers.ts new file mode 100644 index 0000000..449936f --- /dev/null +++ b/frontend/src/app/reducers/front-page.reducers.ts @@ -0,0 +1,27 @@ +import { Action, ActionReducer, createReducer, on } from '@ngrx/store'; +import * as Actions from '../actions/front-page.actions'; + +export interface State { + file: File; + fileName: string; + isFileFetched: boolean; +} + +export const initialState: State = { + file: {} as File, + fileName: '', + isFileFetched: false, +}; + +const _fileReducer = createReducer( + initialState, + on(Actions.fetchFile, (state, { file }) => ({ + file: file, + fileName: file.name, + isFileFetched: true, + })) +); + +export function fileReducer(state: State | undefined, action: Action) { + return _fileReducer(state, action); +} diff --git a/frontend/src/app/reducers/index.ts b/frontend/src/app/reducers/index.ts index aad8dbf..fae1a04 100644 --- a/frontend/src/app/reducers/index.ts +++ b/frontend/src/app/reducers/index.ts @@ -6,19 +6,22 @@ import { MetaReducer, } from '@ngrx/store'; import { environment } from '../../environments/environment'; +import { fileReducer, State as FileState } from './front-page.reducers'; export function debug(reducer: ActionReducer): ActionReducer { return function (state, action) { console.log('State: ', state); - console.log('Action', action); + console.log('Action: ', action); return reducer(state, action); }; } -export interface State {} +export interface State { + fileState: FileState; +} -export const reducers: ActionReducerMap = {}; +export const reducers: ActionReducerMap = { fileState: fileReducer }; export const metaReducers: MetaReducer[] = !environment.production ? [debug] From cf94f6fa883100e08d5c3c5a15337ad2d639383b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Romaszkin?= Date: Sat, 7 Nov 2020 12:10:34 +0100 Subject: [PATCH 3/7] Add file selectors --- .../src/app/selectors/front-page.selectors.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 frontend/src/app/selectors/front-page.selectors.ts diff --git a/frontend/src/app/selectors/front-page.selectors.ts b/frontend/src/app/selectors/front-page.selectors.ts new file mode 100644 index 0000000..b617c68 --- /dev/null +++ b/frontend/src/app/selectors/front-page.selectors.ts @@ -0,0 +1,20 @@ +import { createSelector } from '@ngrx/store'; +import { State as AppState } from '../reducers/index'; +import { State as FileState } from '../reducers/front-page.reducers'; + +export const selectFeature = (state: AppState) => state.fileState; + +export const selectFile = createSelector( + selectFeature, + (state: FileState) => state.file +); + +export const selectFileName = createSelector( + selectFeature, + (state: FileState) => state.fileName +); + +export const selectFetchStatus = createSelector( + selectFeature, + (state: FileState) => state.isFileFetched +); From 89ecf13ab553a36f7494ea20b91db65eb40e5c8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Romaszkin?= Date: Sat, 7 Nov 2020 17:01:09 +0100 Subject: [PATCH 4/7] File choosing now works with store --- .../app/front-page/front-page.component.html | 4 +- .../app/front-page/front-page.component.ts | 46 +++++++++++-------- frontend/src/app/reducers/index.ts | 8 +--- .../src/app/selectors/front-page.selectors.ts | 6 ++- 4 files changed, 35 insertions(+), 29 deletions(-) diff --git a/frontend/src/app/front-page/front-page.component.html b/frontend/src/app/front-page/front-page.component.html index bc75a9c..9730585 100644 --- a/frontend/src/app/front-page/front-page.component.html +++ b/frontend/src/app/front-page/front-page.component.html @@ -45,8 +45,8 @@ > Wyślij! -

- {{ fileName }} +

+ {{ fileName$ | async }}

diff --git a/frontend/src/app/front-page/front-page.component.ts b/frontend/src/app/front-page/front-page.component.ts index 45e2b92..10bada6 100644 --- a/frontend/src/app/front-page/front-page.component.ts +++ b/frontend/src/app/front-page/front-page.component.ts @@ -1,32 +1,42 @@ -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { SendDataService } from '../_services/send-data.service'; import { SharedDataService } from '../_services/shared-data.service'; import { HttpErrorResponse } from '@angular/common/http'; import { NbToastrService } from '@nebular/theme'; import { Store } from '@ngrx/store'; -import { State } from '../reducers/front-page.reducers'; +import { State } from '../reducers/index'; import { Observable } from 'rxjs'; +import * as Selectors from '../selectors/front-page.selectors'; +import { fetchFile } from '../actions/front-page.actions'; @Component({ selector: 'app-front-page', templateUrl: './front-page.component.html', styleUrls: ['./front-page.component.scss'], }) -export class FrontPageComponent { +export class FrontPageComponent implements OnInit { // private file: File; // public fileName: string; // public isFileFetched: boolean; file$: Observable; + fileName$: Observable; + isFileFetched: Observable; constructor( private sendDataService: SendDataService, private sharedDataService: SharedDataService, private router: Router, private toastService: NbToastrService, - private store: Store<{ fileState: State }> + private store: Store ) {} + ngOnInit() { + this.file$ = this.store.select(Selectors.selectFile); + this.fileName$ = this.store.select(Selectors.selectFileName); + this.isFileFetched = this.store.select(Selectors.selectFetchStatus); + } + scrollTo(el: HTMLElement) { el.scrollIntoView({ behavior: 'smooth' }); } @@ -41,25 +51,25 @@ export class FrontPageComponent { } fetchFile(event: any): void { - this.store; + this.store.dispatch(fetchFile({ file: event.target.files[0] })); // this.file = event.target.files[0]; // this.fileName = this.file.name; // this.isFileFetched = true; } sendFile(event: any): void { - this.sendDataService.postFile(this.file).subscribe( - (res: any) => { - this.sharedDataService.setData(res); - this.router.navigate(['/view']); - }, - (error: HttpErrorResponse) => { - if (error.status === 406) { - this.toastService.danger('', 'Format pliku jest niepoprawny!', { - icon: 'alert-circle', - }); - } - } - ); + // this.sendDataService.postFile(this.file).subscribe( + // (res: any) => { + // this.sharedDataService.setData(res); + // this.router.navigate(['/view']); + // }, + // (error: HttpErrorResponse) => { + // if (error.status === 406) { + // this.toastService.danger('', 'Format pliku jest niepoprawny!', { + // icon: 'alert-circle', + // }); + // } + // } + // ); } } diff --git a/frontend/src/app/reducers/index.ts b/frontend/src/app/reducers/index.ts index fae1a04..52b75f6 100644 --- a/frontend/src/app/reducers/index.ts +++ b/frontend/src/app/reducers/index.ts @@ -1,10 +1,4 @@ -import { - ActionReducer, - ActionReducerMap, - createFeatureSelector, - createSelector, - MetaReducer, -} from '@ngrx/store'; +import { ActionReducer, ActionReducerMap, MetaReducer } from '@ngrx/store'; import { environment } from '../../environments/environment'; import { fileReducer, State as FileState } from './front-page.reducers'; diff --git a/frontend/src/app/selectors/front-page.selectors.ts b/frontend/src/app/selectors/front-page.selectors.ts index b617c68..fddd7af 100644 --- a/frontend/src/app/selectors/front-page.selectors.ts +++ b/frontend/src/app/selectors/front-page.selectors.ts @@ -1,8 +1,10 @@ -import { createSelector } from '@ngrx/store'; +import { createSelector, createFeatureSelector } from '@ngrx/store'; import { State as AppState } from '../reducers/index'; import { State as FileState } from '../reducers/front-page.reducers'; -export const selectFeature = (state: AppState) => state.fileState; +export const selectFeature = createFeatureSelector( + 'fileState' +); export const selectFile = createSelector( selectFeature, From b8a0690b660dbe3b5af788af5977141338625418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Romaszkin?= Date: Sat, 7 Nov 2020 19:39:31 +0100 Subject: [PATCH 5/7] Catch error effect --- .../src/app/actions/front-page.actions.ts | 5 ++ .../src/app/effects/front-page.effects.ts | 62 +++++++++++++++++++ .../app/front-page/front-page.component.html | 2 +- .../app/front-page/front-page.component.ts | 10 ++- .../src/app/front-page/front-page.module.ts | 3 + 5 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 frontend/src/app/effects/front-page.effects.ts diff --git a/frontend/src/app/actions/front-page.actions.ts b/frontend/src/app/actions/front-page.actions.ts index 55bee6e..65aba12 100644 --- a/frontend/src/app/actions/front-page.actions.ts +++ b/frontend/src/app/actions/front-page.actions.ts @@ -5,3 +5,8 @@ export const fetchFile = createAction( props<{ file: File }>() ); export const sendFile = createAction('[FrontPage Component] Send File'); + +export const sendFileError = createAction( + '[FrontPage Component] Send Error', + props<{ error: string }>() +); diff --git a/frontend/src/app/effects/front-page.effects.ts b/frontend/src/app/effects/front-page.effects.ts new file mode 100644 index 0000000..09ea5b8 --- /dev/null +++ b/frontend/src/app/effects/front-page.effects.ts @@ -0,0 +1,62 @@ +import { Injectable } from '@angular/core'; +import { SendDataService } from '../_services/send-data.service'; +import * as FrontPageActions from '../actions/front-page.actions'; +import * as FrontPageSelectors from '../selectors/front-page.selectors'; +import { Actions, ofType, createEffect } from '@ngrx/effects'; +import { State as AppState } from '../reducers/index'; +import { Store } from '@ngrx/store'; +import { + exhaustMap, + withLatestFrom, + tap, + map, + catchError, + concatMap, + flatMap, +} from 'rxjs/operators'; +import { of } from 'rxjs'; +import { HttpErrorResponse } from '@angular/common/http'; + +@Injectable() +export class FrontPageEffect { + constructor( + private sendDataService: SendDataService, + private actions$: Actions, + private store$: Store + ) {} + + file$ = createEffect( + () => + this.actions$.pipe( + ofType(FrontPageActions.sendFile), + concatMap((action) => + of(action).pipe( + withLatestFrom(this.store$.select(FrontPageSelectors.selectFile)) + ) + ), + flatMap(([_, file]) => { + return this.sendDataService + .postFile(file) + .pipe( + catchError((error) => + of(FrontPageActions.sendFileError({ error })) + ) + ); + }) + ) + // this.actions$.pipe( + // ofType(FrontPageActions.sendFile), + // map((action) => + // of(action).pipe( + // withLatestFrom(this.store$.select(FrontPageSelectors.selectFile)))) + // ) + // this.actions$.pipe( + // ofType(FrontPageActions.sendFile), + // exhaustMap((action) => + // of(action).pipe( + // withLatestFrom(this.store$.select(FrontPageSelectors.selectFile)) + // ) + // ) + // ), + ); +} diff --git a/frontend/src/app/front-page/front-page.component.html b/frontend/src/app/front-page/front-page.component.html index 9730585..eca668e 100644 --- a/frontend/src/app/front-page/front-page.component.html +++ b/frontend/src/app/front-page/front-page.component.html @@ -41,7 +41,7 @@ nbButton status="success" (click)="sendFile($event)" - [disabled]="!isFileFetched" + [disabled]="!(isFileFetched$ | async)" > Wyślij! diff --git a/frontend/src/app/front-page/front-page.component.ts b/frontend/src/app/front-page/front-page.component.ts index 10bada6..7ffb24b 100644 --- a/frontend/src/app/front-page/front-page.component.ts +++ b/frontend/src/app/front-page/front-page.component.ts @@ -8,7 +8,7 @@ import { Store } from '@ngrx/store'; import { State } from '../reducers/index'; import { Observable } from 'rxjs'; import * as Selectors from '../selectors/front-page.selectors'; -import { fetchFile } from '../actions/front-page.actions'; +import { fetchFile, sendFile } from '../actions/front-page.actions'; @Component({ selector: 'app-front-page', @@ -21,7 +21,7 @@ export class FrontPageComponent implements OnInit { // public isFileFetched: boolean; file$: Observable; fileName$: Observable; - isFileFetched: Observable; + isFileFetched$: Observable; constructor( private sendDataService: SendDataService, @@ -34,7 +34,7 @@ export class FrontPageComponent implements OnInit { ngOnInit() { this.file$ = this.store.select(Selectors.selectFile); this.fileName$ = this.store.select(Selectors.selectFileName); - this.isFileFetched = this.store.select(Selectors.selectFetchStatus); + this.isFileFetched$ = this.store.select(Selectors.selectFetchStatus); } scrollTo(el: HTMLElement) { @@ -52,12 +52,10 @@ export class FrontPageComponent implements OnInit { fetchFile(event: any): void { this.store.dispatch(fetchFile({ file: event.target.files[0] })); - // this.file = event.target.files[0]; - // this.fileName = this.file.name; - // this.isFileFetched = true; } sendFile(event: any): void { + this.store.dispatch({ type: '[FrontPage Component] Send File' }); // this.sendDataService.postFile(this.file).subscribe( // (res: any) => { // this.sharedDataService.setData(res); diff --git a/frontend/src/app/front-page/front-page.module.ts b/frontend/src/app/front-page/front-page.module.ts index 32131dd..5747519 100644 --- a/frontend/src/app/front-page/front-page.module.ts +++ b/frontend/src/app/front-page/front-page.module.ts @@ -9,6 +9,8 @@ import { NbIconModule, NbStepperModule, } from '@nebular/theme'; +import { EffectsModule } from '@ngrx/effects'; +import { FrontPageEffect } from '../effects/front-page.effects'; @NgModule({ declarations: [FrontPageComponent], @@ -19,6 +21,7 @@ import { NbCardModule, NbIconModule, NbStepperModule, + EffectsModule.forFeature([FrontPageEffect]), ], providers: [SendDataService], }) From 4ffda135a3729353d6ac13ce7c9c4dffbde40a8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Romaszkin?= Date: Sun, 8 Nov 2020 14:33:39 +0100 Subject: [PATCH 6/7] Move front page file loading into store --- .../src/app/_services/send-data.service.ts | 2 +- .../src/app/actions/front-page.actions.ts | 8 +- .../src/app/effects/front-page.effects.ts | 73 +++++++++++-------- .../src/app/reducers/front-page.reducers.ts | 23 +++++- frontend/src/app/reducers/index.ts | 13 +++- 5 files changed, 81 insertions(+), 38 deletions(-) diff --git a/frontend/src/app/_services/send-data.service.ts b/frontend/src/app/_services/send-data.service.ts index cc0e3a9..82a38f7 100644 --- a/frontend/src/app/_services/send-data.service.ts +++ b/frontend/src/app/_services/send-data.service.ts @@ -6,7 +6,7 @@ import { Observable } from 'rxjs'; export class SendDataService { constructor(private http: HttpClient) {} - postFile(file: File): Observable { + postFile(file: File): Observable { const formData: FormData = new FormData(); const requestOptions = { responseType: 'text' as 'json', diff --git a/frontend/src/app/actions/front-page.actions.ts b/frontend/src/app/actions/front-page.actions.ts index 65aba12..f66a45f 100644 --- a/frontend/src/app/actions/front-page.actions.ts +++ b/frontend/src/app/actions/front-page.actions.ts @@ -1,3 +1,4 @@ +import { HttpErrorResponse } from '@angular/common/http'; import { createAction, props } from '@ngrx/store'; export const fetchFile = createAction( @@ -8,5 +9,10 @@ export const sendFile = createAction('[FrontPage Component] Send File'); export const sendFileError = createAction( '[FrontPage Component] Send Error', - props<{ error: string }>() + props<{ error: HttpErrorResponse }>() +); + +export const sendFileSuccess = createAction( + '[FrontPage Component] Send Success', + props<{ data: string }>() ); diff --git a/frontend/src/app/effects/front-page.effects.ts b/frontend/src/app/effects/front-page.effects.ts index 09ea5b8..d03d62d 100644 --- a/frontend/src/app/effects/front-page.effects.ts +++ b/frontend/src/app/effects/front-page.effects.ts @@ -15,48 +15,57 @@ import { flatMap, } from 'rxjs/operators'; import { of } from 'rxjs'; -import { HttpErrorResponse } from '@angular/common/http'; +import { NbToastrService } from '@nebular/theme'; +import { Router } from '@angular/router'; @Injectable() export class FrontPageEffect { constructor( private sendDataService: SendDataService, private actions$: Actions, - private store$: Store + private store$: Store, + private toastService: NbToastrService, + private router: Router ) {} - file$ = createEffect( + file$ = createEffect(() => + this.actions$.pipe( + ofType(FrontPageActions.sendFile), + concatMap((action) => + of(action).pipe( + withLatestFrom(this.store$.select(FrontPageSelectors.selectFile)) + ) + ), + flatMap(([_, file]) => + this.sendDataService.postFile(file).pipe( + map((result) => FrontPageActions.sendFileSuccess({ data: result })), + catchError((error) => of(FrontPageActions.sendFileError({ error }))) + ) + ) + ) + ); + + toast$ = createEffect( () => this.actions$.pipe( - ofType(FrontPageActions.sendFile), - concatMap((action) => - of(action).pipe( - withLatestFrom(this.store$.select(FrontPageSelectors.selectFile)) - ) - ), - flatMap(([_, file]) => { - return this.sendDataService - .postFile(file) - .pipe( - catchError((error) => - of(FrontPageActions.sendFileError({ error })) - ) - ); + ofType(FrontPageActions.sendFileError), + tap(({ error }) => { + if (error.status === 406) { + this.toastService.danger('', 'Format pliku jest niepoprawny!', { + icon: 'alert-circle', + }); + } }) - ) - // this.actions$.pipe( - // ofType(FrontPageActions.sendFile), - // map((action) => - // of(action).pipe( - // withLatestFrom(this.store$.select(FrontPageSelectors.selectFile)))) - // ) - // this.actions$.pipe( - // ofType(FrontPageActions.sendFile), - // exhaustMap((action) => - // of(action).pipe( - // withLatestFrom(this.store$.select(FrontPageSelectors.selectFile)) - // ) - // ) - // ), + ), + { dispatch: false } + ); + + navigate$ = createEffect( + () => + this.actions$.pipe( + ofType(FrontPageActions.sendFileSuccess), + tap(() => this.router.navigate(['/view'])) + ), + { dispatch: false } ); } diff --git a/frontend/src/app/reducers/front-page.reducers.ts b/frontend/src/app/reducers/front-page.reducers.ts index 449936f..956ac7c 100644 --- a/frontend/src/app/reducers/front-page.reducers.ts +++ b/frontend/src/app/reducers/front-page.reducers.ts @@ -1,4 +1,4 @@ -import { Action, ActionReducer, createReducer, on } from '@ngrx/store'; +import { Action, createReducer, on } from '@ngrx/store'; import * as Actions from '../actions/front-page.actions'; export interface State { @@ -7,21 +7,40 @@ export interface State { isFileFetched: boolean; } +export interface DataState { + data: any; +} + export const initialState: State = { file: {} as File, fileName: '', isFileFetched: false, }; +export const initialDataState: DataState = { + data: '', +}; + const _fileReducer = createReducer( initialState, - on(Actions.fetchFile, (state, { file }) => ({ + on(Actions.fetchFile, (_, { file }) => ({ file: file, fileName: file.name, isFileFetched: true, })) ); +const _dataReducer = createReducer( + initialDataState, + on(Actions.sendFileSuccess, (_, { data }) => { + return { data: data }; + }) +); + export function fileReducer(state: State | undefined, action: Action) { return _fileReducer(state, action); } + +export function dataReducer(state: DataState | undefined, action: Action) { + return _dataReducer(state, action); +} diff --git a/frontend/src/app/reducers/index.ts b/frontend/src/app/reducers/index.ts index 52b75f6..3b4156e 100644 --- a/frontend/src/app/reducers/index.ts +++ b/frontend/src/app/reducers/index.ts @@ -1,6 +1,11 @@ import { ActionReducer, ActionReducerMap, MetaReducer } from '@ngrx/store'; import { environment } from '../../environments/environment'; -import { fileReducer, State as FileState } from './front-page.reducers'; +import { + fileReducer, + State as FileState, + DataState, + dataReducer, +} from './front-page.reducers'; export function debug(reducer: ActionReducer): ActionReducer { return function (state, action) { @@ -13,9 +18,13 @@ export function debug(reducer: ActionReducer): ActionReducer { export interface State { fileState: FileState; + data: DataState; } -export const reducers: ActionReducerMap = { fileState: fileReducer }; +export const reducers: ActionReducerMap = { + fileState: fileReducer, + data: dataReducer, +}; export const metaReducers: MetaReducer[] = !environment.production ? [debug] From a008e0d120818a40fd65214d48566aafa3a69813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Romaszkin?= Date: Sun, 8 Nov 2020 15:00:21 +0100 Subject: [PATCH 7/7] Front page component code cleanup --- .../app/front-page/front-page.component.ts | 29 +------------------ 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/frontend/src/app/front-page/front-page.component.ts b/frontend/src/app/front-page/front-page.component.ts index 7ffb24b..7f2baf0 100644 --- a/frontend/src/app/front-page/front-page.component.ts +++ b/frontend/src/app/front-page/front-page.component.ts @@ -1,9 +1,4 @@ import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; -import { SendDataService } from '../_services/send-data.service'; -import { SharedDataService } from '../_services/shared-data.service'; -import { HttpErrorResponse } from '@angular/common/http'; -import { NbToastrService } from '@nebular/theme'; import { Store } from '@ngrx/store'; import { State } from '../reducers/index'; import { Observable } from 'rxjs'; @@ -16,20 +11,11 @@ import { fetchFile, sendFile } from '../actions/front-page.actions'; styleUrls: ['./front-page.component.scss'], }) export class FrontPageComponent implements OnInit { - // private file: File; - // public fileName: string; - // public isFileFetched: boolean; file$: Observable; fileName$: Observable; isFileFetched$: Observable; - constructor( - private sendDataService: SendDataService, - private sharedDataService: SharedDataService, - private router: Router, - private toastService: NbToastrService, - private store: Store - ) {} + constructor(private store: Store) {} ngOnInit() { this.file$ = this.store.select(Selectors.selectFile); @@ -56,18 +42,5 @@ export class FrontPageComponent implements OnInit { sendFile(event: any): void { this.store.dispatch({ type: '[FrontPage Component] Send File' }); - // this.sendDataService.postFile(this.file).subscribe( - // (res: any) => { - // this.sharedDataService.setData(res); - // this.router.navigate(['/view']); - // }, - // (error: HttpErrorResponse) => { - // if (error.status === 406) { - // this.toastService.danger('', 'Format pliku jest niepoprawny!', { - // icon: 'alert-circle', - // }); - // } - // } - // ); } }