Skip to content

Commit

Permalink
refactor(Example): use createEffect
Browse files Browse the repository at this point in the history
  • Loading branch information
timdeschryver committed Mar 30, 2019
1 parent c0466ac commit 36a4eeb
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 92 deletions.
76 changes: 43 additions & 33 deletions projects/example-app/src/app/auth/effects/auth.effects.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material';
import { Router } from '@angular/router';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { Actions, ofType, createEffect } from '@ngrx/effects';
import { of } from 'rxjs';
import { catchError, exhaustMap, map, tap } from 'rxjs/operators';
import {
Expand All @@ -15,47 +15,57 @@ import { LogoutConfirmationDialogComponent } from '@example-app/auth/components/

@Injectable()
export class AuthEffects {
@Effect()
login$ = this.actions$.pipe(
ofType(LoginPageActions.login.type),
map(action => action.credentials),
exhaustMap((auth: Credentials) =>
this.authService.login(auth).pipe(
map(user => AuthApiActions.loginSuccess({ user })),
catchError(error => of(AuthApiActions.loginFailure({ error })))
login$ = createEffect(() =>
this.actions$.pipe(
ofType(LoginPageActions.login.type),
map(action => action.credentials),
exhaustMap((auth: Credentials) =>
this.authService.login(auth).pipe(
map(user => AuthApiActions.loginSuccess({ user })),
catchError(error => of(AuthApiActions.loginFailure({ error })))
)
)
)
);

@Effect({ dispatch: false })
loginSuccess$ = this.actions$.pipe(
ofType(AuthApiActions.loginSuccess.type),
tap(() => this.router.navigate(['/']))
loginSuccess$ = createEffect(
() =>
this.actions$.pipe(
ofType(AuthApiActions.loginSuccess.type),
tap(() => this.router.navigate(['/']))
),
{ dispatch: false }
);

@Effect({ dispatch: false })
loginRedirect$ = this.actions$.pipe(
ofType(AuthApiActions.loginRedirect.type, AuthActions.logout.type),
tap(authed => {
this.router.navigate(['/login']);
})
loginRedirect$ = createEffect(
() =>
this.actions$.pipe(
ofType(AuthApiActions.loginRedirect.type, AuthActions.logout.type),
tap(authed => {
this.router.navigate(['/login']);
})
),
{ dispatch: false }
);

@Effect()
logoutConfirmation$ = this.actions$.pipe(
ofType(AuthActions.logoutConfirmation.type),
exhaustMap(() => {
const dialogRef = this.dialog.open<
LogoutConfirmationDialogComponent,
undefined,
boolean
>(LogoutConfirmationDialogComponent);
logoutConfirmation$ = createEffect(() =>
this.actions$.pipe(
ofType(AuthActions.logoutConfirmation.type),
exhaustMap(() => {
const dialogRef = this.dialog.open<
LogoutConfirmationDialogComponent,
undefined,
boolean
>(LogoutConfirmationDialogComponent);

return dialogRef.afterClosed();
}),
map(
result =>
result ? AuthActions.logout() : AuthActions.logoutConfirmationDismiss()
return dialogRef.afterClosed();
}),
map(
result =>
result
? AuthActions.logout()
: AuthActions.logoutConfirmationDismiss()
)
)
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { TestBed } from '@angular/core/testing';
import { Actions } from '@ngrx/effects';
import { provideMockActions } from '@ngrx/effects/testing';
import { cold, getTestScheduler, hot } from 'jasmine-marbles';
import { empty, Observable } from 'rxjs';
import { Observable } from 'rxjs';

import { GoogleBooksService } from '@example-app/core/services/google-books.service';
import {
Expand Down
54 changes: 26 additions & 28 deletions projects/example-app/src/app/books/effects/book.effects.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Inject, Injectable, InjectionToken, Optional } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { Action } from '@ngrx/store';
import { asyncScheduler, EMPTY as empty, Observable, of } from 'rxjs';
import { Injectable } from '@angular/core';
import { Actions, ofType, createEffect } from '@ngrx/effects';
import { asyncScheduler, EMPTY as empty, of } from 'rxjs';
import {
catchError,
debounceTime,
Expand Down Expand Up @@ -31,32 +30,31 @@ import { Book } from '@example-app/books/models/book';

@Injectable()
export class BookEffects {
@Effect()
search$ = ({ debounce = 300, scheduler = asyncScheduler } = {}): Observable<
Action
> =>
this.actions$.pipe(
ofType(FindBookPageActions.searchBooks.type),
debounceTime(debounce, scheduler),
switchMap(({ query }) => {
if (query === '') {
return empty;
}
search$ = createEffect(
() => ({ debounce = 300, scheduler = asyncScheduler } = {}) =>
this.actions$.pipe(
ofType(FindBookPageActions.searchBooks.type),
debounceTime(debounce, scheduler),
switchMap(({ query }) => {
if (query === '') {
return empty;
}

const nextSearch$ = this.actions$.pipe(
ofType(FindBookPageActions.searchBooks.type),
skip(1)
);
const nextSearch$ = this.actions$.pipe(
ofType(FindBookPageActions.searchBooks.type),
skip(1)
);

return this.googleBooks.searchBooks(query).pipe(
takeUntil(nextSearch$),
map((books: Book[]) => BooksApiActions.searchSuccess({ books })),
catchError(err =>
of(BooksApiActions.searchFailure({ errorMsg: err }))
)
);
})
);
return this.googleBooks.searchBooks(query).pipe(
takeUntil(nextSearch$),
map((books: Book[]) => BooksApiActions.searchSuccess({ books })),
catchError(err =>
of(BooksApiActions.searchFailure({ errorMsg: err }))
)
);
})
)
);

constructor(
private actions$: Actions<FindBookPageActions.FindBookPageActionsUnion>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Database } from '@ngrx/db';
import { Actions } from '@ngrx/effects';
import { provideMockActions } from '@ngrx/effects/testing';
import { cold, hot } from 'jasmine-marbles';
import { empty, Observable } from 'rxjs';
import { Observable } from 'rxjs';

import {
CollectionApiActions,
Expand Down
60 changes: 31 additions & 29 deletions projects/example-app/src/app/books/effects/collection.effects.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Injectable } from '@angular/core';
import { Database } from '@ngrx/db';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { Action } from '@ngrx/store';
import { defer, Observable, of } from 'rxjs';
import { Actions, Effect, ofType, createEffect } from '@ngrx/effects';
import { defer, of } from 'rxjs';
import { catchError, map, mergeMap, switchMap, toArray } from 'rxjs/operators';

import { Book } from '@example-app/books/models/book';
Expand All @@ -25,44 +24,47 @@ export class CollectionEffects {
* effect easier to test.
*/
@Effect({ dispatch: false })
openDB$: Observable<any> = defer(() => {
openDB$ = defer(() => {
return this.db.open('books_app');
});

@Effect()
loadCollection$: Observable<Action> = this.actions$.pipe(
ofType(CollectionPageActions.loadCollection.type),
switchMap(() =>
this.db.query('books').pipe(
toArray(),
map((books: Book[]) =>
CollectionApiActions.loadBooksSuccess({ books })
),
catchError(error =>
of(CollectionApiActions.loadBooksFailure({ error }))
loadCollection$ = createEffect(() =>
this.actions$.pipe(
ofType(CollectionPageActions.loadCollection.type),
switchMap(() =>
this.db.query('books').pipe(
toArray(),
map((books: Book[]) =>
CollectionApiActions.loadBooksSuccess({ books })
),
catchError(error =>
of(CollectionApiActions.loadBooksFailure({ error }))
)
)
)
)
);

@Effect()
addBookToCollection$: Observable<Action> = this.actions$.pipe(
ofType(SelectedBookPageActions.addBook.type),
mergeMap(({ book }) =>
this.db.insert('books', [book]).pipe(
map(() => CollectionApiActions.addBookSuccess({ book })),
catchError(() => of(CollectionApiActions.addBookFailure({ book })))
addBookToCollection$ = createEffect(() =>
this.actions$.pipe(
ofType(SelectedBookPageActions.addBook.type),
mergeMap(({ book }) =>
this.db.insert('books', [book]).pipe(
map(() => CollectionApiActions.addBookSuccess({ book })),
catchError(() => of(CollectionApiActions.addBookFailure({ book })))
)
)
)
);

@Effect()
removeBookFromCollection$: Observable<Action> = this.actions$.pipe(
ofType(SelectedBookPageActions.removeBook.type),
mergeMap(({ book }) =>
this.db.executeWrite('books', 'delete', [book.id]).pipe(
map(() => CollectionApiActions.removeBookSuccess({ book })),
catchError(() => of(CollectionApiActions.removeBookFailure({ book })))
removeBookFromCollection$ = createEffect(() =>
this.actions$.pipe(
ofType(SelectedBookPageActions.removeBook.type),
mergeMap(({ book }) =>
this.db.executeWrite('books', 'delete', [book.id]).pipe(
map(() => CollectionApiActions.removeBookSuccess({ book })),
catchError(() => of(CollectionApiActions.removeBookFailure({ book })))
)
)
)
);
Expand Down

0 comments on commit 36a4eeb

Please sign in to comment.