Skip to content

Commit e463891

Browse files
authored
Merge pull request #3 from renantee/course-project
Course Project: Using NgRx Framework
2 parents 5f14792 + 7077de4 commit e463891

29 files changed

+954
-294
lines changed

course-project/package-lock.json

+33
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

course-project/package.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
"@angular/platform-browser": "~10.0.9",
2020
"@angular/platform-browser-dynamic": "~10.0.9",
2121
"@angular/router": "~10.0.9",
22+
"@ngrx/effects": "^10.0.0",
23+
"@ngrx/router-store": "^10.0.0",
24+
"@ngrx/store": "^10.0.0",
2225
"bootstrap": "^3.4.1",
2326
"rxjs": "~6.5.5",
2427
"rxjs-compat": "^6.6.2",
@@ -29,9 +32,10 @@
2932
"@angular-devkit/build-angular": "~0.1000.6",
3033
"@angular/cli": "~10.0.6",
3134
"@angular/compiler-cli": "~10.0.9",
32-
"@types/node": "^12.11.1",
35+
"@ngrx/store-devtools": "^10.0.0",
3336
"@types/jasmine": "~3.5.0",
3437
"@types/jasminewd2": "~2.0.3",
38+
"@types/node": "^12.11.1",
3539
"codelyzer": "^6.0.0",
3640
"jasmine-core": "~3.5.0",
3741
"jasmine-spec-reporter": "~5.0.0",
+5-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { Component, OnInit } from '@angular/core';
2+
import { Store } from '@ngrx/store';
23

3-
import { AuthService } from './auth/auth.service';
44
import { LoggingService } from './logging.service';
5+
import * as fromApp from './store/app.reducer';
6+
import * as AuthActions from './auth/store/auth.actions';
57

68
@Component({
79
selector: 'app-root',
@@ -10,12 +12,12 @@ import { LoggingService } from './logging.service';
1012
})
1113
export class AppComponent implements OnInit {
1214
constructor(
13-
private authService: AuthService,
15+
private store: Store<fromApp.AppState>,
1416
private loggingService: LoggingService
1517
) {}
1618

1719
ngOnInit() {
18-
this.authService.autoLogin();
20+
this.store.dispatch(new AuthActions.AutoLogin());
1921
this.loggingService.printLog('Hello from AppComponent ngOnInit');
2022
}
2123
}

course-project/src/app/app.module.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,35 @@
11
import { BrowserModule } from '@angular/platform-browser';
22
import { NgModule } from '@angular/core';
33
import { HttpClientModule } from '@angular/common/http';
4+
import { StoreModule } from '@ngrx/store';
5+
import { EffectsModule } from '@ngrx/effects';
6+
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
7+
import { StoreRouterConnectingModule } from '@ngrx/router-store';
48

59
import { AppComponent } from './app.component';
610
import { HeaderComponent } from './header/header.component';
711
import { AppRoutingModule } from './app-routing.module';
812
import { SharedModule } from './shared/shared.module';
913
import { CoreModule } from './core.module';
10-
import { LoggingService } from './logging.service';
14+
import * as fromApp from './store/app.reducer';
15+
import { AuthEffects } from './auth/store/auth.effects';
16+
import { environment } from '../environments/environment';
17+
import { RecipeEffects } from './recipes/store/recipe.effects';
1118

1219
@NgModule({
1320
declarations: [AppComponent, HeaderComponent],
1421
imports: [
1522
BrowserModule,
1623
HttpClientModule,
1724
AppRoutingModule,
25+
StoreModule.forRoot(fromApp.appReducer),
26+
EffectsModule.forRoot([AuthEffects, RecipeEffects]),
27+
StoreDevtoolsModule.instrument({ logOnly: environment.production }),
28+
StoreRouterConnectingModule.forRoot(),
1829
SharedModule,
1930
CoreModule
2031
],
21-
bootstrap: [AppComponent],
32+
bootstrap: [AppComponent]
2233
// providers: [LoggingService]
2334
})
2435
export class AppModule {}

course-project/src/app/auth/auth-interceptor.service.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,22 @@ import {
55
HttpHandler,
66
HttpParams
77
} from '@angular/common/http';
8-
import { take, exhaustMap } from 'rxjs/operators';
8+
import { take, exhaustMap, map } from 'rxjs/operators';
9+
import { Store } from '@ngrx/store';
910

1011
import { AuthService } from './auth.service';
12+
import * as fromApp from '../store/app.reducer';
1113

1214
@Injectable()
1315
export class AuthInterceptorService implements HttpInterceptor {
14-
constructor(private authService: AuthService) {}
16+
constructor(private authService: AuthService, private store: Store<fromApp.AppState>) {}
1517

1618
intercept(req: HttpRequest<any>, next: HttpHandler) {
17-
return this.authService.user.pipe(
19+
return this.store.select('auth').pipe(
1820
take(1),
21+
map(authState => {
22+
return authState.user;
23+
}),
1924
exhaustMap(user => {
2025
if (!user) {
2126
return next.handle(req);

course-project/src/app/auth/auth.component.ts

+31-29
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,46 @@ import {
22
Component,
33
ComponentFactoryResolver,
44
ViewChild,
5-
OnDestroy
5+
OnDestroy,
6+
OnInit
67
} from '@angular/core';
78
import { NgForm } from '@angular/forms';
8-
import { Router } from '@angular/router';
9-
import { Observable, Subscription } from 'rxjs';
9+
import { Subscription } from 'rxjs';
10+
import { Store } from '@ngrx/store';
1011

11-
import { AuthService, AuthResponseData } from './auth.service';
1212
import { AlertComponent } from '../shared/alert/alert.component';
1313
import { PlaceholderDirective } from '../shared/placeholder/placeholder.directive';
14+
import * as fromApp from '../store/app.reducer';
15+
import * as AuthActions from './store/auth.actions';
1416

1517
@Component({
1618
selector: 'app-auth',
1719
templateUrl: './auth.component.html'
1820
})
19-
export class AuthComponent implements OnDestroy {
21+
export class AuthComponent implements OnInit, OnDestroy {
2022
isLoginMode = true;
2123
isLoading = false;
2224
error: string = null;
2325
@ViewChild(PlaceholderDirective, { static: false }) alertHost: PlaceholderDirective;
2426

2527
private closeSub: Subscription;
28+
private storeSub: Subscription;
2629

2730
constructor(
28-
private authService: AuthService,
29-
private router: Router,
30-
private componentFactoryResolver: ComponentFactoryResolver
31+
private componentFactoryResolver: ComponentFactoryResolver,
32+
private store: Store<fromApp.AppState>
3133
) {}
3234

35+
ngOnInit() {
36+
this.storeSub = this.store.select('auth').subscribe(authState => {
37+
this.isLoading = authState.loading;
38+
this.error = authState.authError;
39+
if (this.error) {
40+
this.showErrorAlert(this.error);
41+
}
42+
});
43+
}
44+
3345
onSwitchMode() {
3446
this.isLoginMode = !this.isLoginMode;
3547
}
@@ -41,41 +53,31 @@ export class AuthComponent implements OnDestroy {
4153
const email = form.value.email;
4254
const password = form.value.password;
4355

44-
let authObs: Observable<AuthResponseData>;
45-
46-
this.isLoading = true;
47-
4856
if (this.isLoginMode) {
49-
authObs = this.authService.login(email, password);
57+
// authObs = this.authService.login(email, password);
58+
this.store.dispatch(
59+
new AuthActions.LoginStart({ email: email, password: password })
60+
);
5061
} else {
51-
authObs = this.authService.signup(email, password);
62+
this.store.dispatch(
63+
new AuthActions.SignupStart({ email: email, password: password })
64+
);
5265
}
5366

54-
authObs.subscribe(
55-
resData => {
56-
console.log(resData);
57-
this.isLoading = false;
58-
this.router.navigate(['/recipes']);
59-
},
60-
errorMessage => {
61-
console.log(errorMessage);
62-
this.error = errorMessage;
63-
this.showErrorAlert(errorMessage);
64-
this.isLoading = false;
65-
}
66-
);
67-
6867
form.reset();
6968
}
7069

7170
onHandleError() {
72-
this.error = null;
71+
this.store.dispatch(new AuthActions.ClearError());
7372
}
7473

7574
ngOnDestroy() {
7675
if (this.closeSub) {
7776
this.closeSub.unsubscribe();
7877
}
78+
if (this.storeSub) {
79+
this.storeSub.unsubscribe();
80+
}
7981
}
8082

8183
private showErrorAlert(message: string) {

course-project/src/app/auth/auth.guard.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,18 @@ import {
88
import { Injectable } from '@angular/core';
99
import { Observable } from 'rxjs';
1010
import { map, tap, take } from 'rxjs/operators';
11+
import { Store } from '@ngrx/store';
1112

1213
import { AuthService } from './auth.service';
14+
import * as fromApp from '../store/app.reducer';
1315

1416
@Injectable({ providedIn: 'root' })
1517
export class AuthGuard implements CanActivate {
16-
constructor(private authService: AuthService, private router: Router) {}
18+
constructor(
19+
private authService: AuthService,
20+
private router: Router,
21+
private store: Store<fromApp.AppState>
22+
) {}
1723

1824
canActivate(
1925
route: ActivatedRouteSnapshot,
@@ -23,8 +29,11 @@ export class AuthGuard implements CanActivate {
2329
| UrlTree
2430
| Promise<boolean | UrlTree>
2531
| Observable<boolean | UrlTree> {
26-
return this.authService.user.pipe(
32+
return this.store.select('auth').pipe(
2733
take(1),
34+
map(authState => {
35+
return authState.user;
36+
}),
2837
map(user => {
2938
const isAuth = !!user;
3039
if (isAuth) {

0 commit comments

Comments
 (0)