Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The Role of Effects in NgRx Authentication

The Role of Effects in NgRx Authentication

Building token authentication into an NgRx application can be overwhelming and confusing. Authentication is already a big, scary subject and so is NgRx. When you put them together, things get confusing fast. In this talk, we’ll do a comparison of how authentication in a vanilla Angular app differs from auth in an NgRx app. We’ll then see how the central nervous system of authentication shifts from a service in regular Angular to Effects in NgRx.

This talk will be practical and code-driven, leaving you equipped to tackle adding this feature to your NgRx application at work on Monday. You’ll learn how Effects can handle loading authentication state, navigate users to protected routes, and process tokens received from an identity provider. By the end, you’ll feel way better about tackling auth in NgRx!

Sam Julien

April 03, 2020
Tweet

More Decks by Sam Julien

Other Decks in Technology

Transcript

  1. The Role of Effects in
    NgRx Authentication

    View Slide

  2. @samjulien

    View Slide

  3. Effects are one of the hardest
    parts of learning NgRx.
    @samjulien

    View Slide

  4. Effects are powerful and can do many things.
    @samjulien

    View Slide

  5. Effects are powerful and can do many things.
    @samjulien
    Effects aren’t as concrete as Actions or Reducers.

    View Slide

  6. @samjulien

    View Slide

  7. @samjulien

    +

    View Slide

  8. Effects are a huge part of
    implementing auth in NgRx.
    @samjulien

    View Slide

  9. View Slide

  10. View Slide

  11. View Slide

  12. View Slide

  13. View Slide

  14. View Slide

  15. The Role of Effects in NgRx Auth
    @samjulien

    View Slide

  16. The Role of Effects in NgRx Auth
    @samjulien
    Effects are the DJ of NgRx

    View Slide

  17. The Role of Effects in NgRx Auth
    @samjulien
    Effects are the DJ of NgRx
    Common Struggles with Effects

    View Slide

  18. The Role of Effects in NgRx Auth
    @samjulien
    Effects are the DJ of NgRx
    Common Struggles with Effects
    Effects in the Log In Flow

    View Slide

  19. @samjulien
    Sam Julien
    @samjulien

    View Slide

  20. @samjulien
    Sam Julien
    @samjulien
    Sr. Developer Advocate Engineer at Auth0

    View Slide

  21. @samjulien
    Sam Julien
    @samjulien
    Sr. Developer Advocate Engineer at Auth0
    GDE & Angular Collaborator

    View Slide

  22. @samjulien
    Sam Julien
    @samjulien
    Sr. Developer Advocate Engineer at Auth0
    GDE & Angular Collaborator
    UpgradingAngularJS.com, Thinkster, & egghead

    View Slide

  23. The Role of Effects in NgRx Auth
    @samjulien
    Effects are the DJ of NgRx
    Common Struggles with Effects
    Effects in the Log In Flow

    View Slide

  24. View Slide

  25. @samjulien

    View Slide

  26. Services
    Components
    @samjulien

    View Slide

  27. @samjulien

    View Slide

  28. Services
    Components
    @samjulien

    View Slide

  29. Reducers
    Components
    Effects
    @samjulien

    View Slide

  30. Reducers
    Components
    Effects
    @samjulien

    View Slide

  31. Effects
    @samjulien

    View Slide

  32. Effects
    @samjulien
    Decide when to call services

    View Slide

  33. Effects
    @samjulien
    Decide when to call services
    Communicate with APIs

    View Slide

  34. Effects
    @samjulien
    Handle control flow logic
    Decide when to call services
    Communicate with APIs

    View Slide

  35. @samjulien
    Handle control flow logic

    View Slide

  36. Effects function as a task runner.
    @samjulien

    View Slide

  37. Effects are the brain of NgRx.
    @samjulien

    View Slide

  38. View Slide

  39. The Role of Effects in NgRx Auth
    @samjulien
    Effects are the DJ of NgRx
    Common Struggles with Effects
    Effects in the Log In Flow

    View Slide

  40. Effects: The Struggle
    @samjulien

    View Slide

  41. Effects: The Struggle
    @samjulien
    Actions that only trigger Effects

    View Slide

  42. @samjulien
    Actions that only trigger Effects
    Actions that don’t touch the Reducer to modify state.

    View Slide

  43. Effects: The Struggle
    @samjulien
    Actions that only trigger Effects

    View Slide

  44. Effects: The Struggle
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects

    View Slide

  45. @samjulien
    Effects that don’t return an Action.
    Non-dispatching Effects

    View Slide

  46. Effects: The Struggle
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects

    View Slide

  47. Effects: The Struggle
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects

    View Slide

  48. @samjulien
    Trying to handle multiple side effects at once.
    Writing complex Effects

    View Slide

  49. @samjulien

    +

    View Slide

  50. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects

    View Slide

  51. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects

    View Slide

  52. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects


    View Slide

  53. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects



    View Slide

  54. The Role of Effects in NgRx Auth
    @samjulien
    Effects are the DJ of NgRx
    Common Struggles with Effects
    Effects in the Log In Flow

    View Slide

  55. @samjulien

    +

    View Slide

  56. @samjulien

    View Slide

  57. Start login
    Handle redirect
    Log in to provider
    @samjulien

    View Slide

  58. Handle redirect
    Success
    Error
    @samjulien

    View Slide

  59. Success
    User Token
    @samjulien

    View Slide

  60. Success
    User Token
    Redirect
    @samjulien

    View Slide

  61. @samjulien

    View Slide

  62. Auth Service
    @samjulien

    View Slide

  63. @samjulien
    Auth Service

    View Slide

  64. @samjulien
    Store token and user in memory
    Auth Service

    View Slide

  65. @samjulien
    Store token and user in memory
    Interact with auth SDK
    Auth Service

    View Slide

  66. @samjulien
    Store token and user in memory
    Interact with auth SDK
    Handle all redirect logic
    Auth Service

    View Slide

  67. Auth Service
    Components
    @samjulien

    View Slide

  68. Auth Service
    Components
    Data Services
    @samjulien

    View Slide

  69. @samjulien

    View Slide

  70. Auth Service
    Components
    Data Services
    @samjulien

    View Slide

  71. Reducers
    Components
    Effects
    Auth Service
    @samjulien

    View Slide

  72. @samjulien

    +

    View Slide

  73. @samjulien

    View Slide

  74. Which parts of the auth flow directly
    change State?
    @samjulien

    View Slide

  75. Start login
    Handle redirect
    Log in to provider
    @samjulien

    View Slide

  76. Handle redirect
    Success
    Error
    @samjulien

    View Slide

  77. Success
    @samjulien

    View Slide

  78. Success
    User Token
    @samjulien

    View Slide

  79. Success
    User Token
    Redirect
    @samjulien

    View Slide

  80. Success
    User Token
    Redirect
    @samjulien

    View Slide

  81. export interface State {
    userProfile: UserProfile;
    accessToken: AccessToken;
    }
    @samjulien

    View Slide

  82. Everything else is a side effect!
    @samjulien

    View Slide

  83. Everything else needs Effects!
    @samjulien

    View Slide

  84. Start login
    Handle redirect
    Log in to provider
    @samjulien

    View Slide

  85. Start login
    Log in to provider
    @samjulien

    View Slide

  86. export const logIn = createAction(
    ‘[Auth] Start Log In’
    );
    @samjulien

    View Slide

  87. logIn$ = createEffect(() =>
    this.actions$.pipe(
    ofType(AuthActions.logIn),
    tap(() => this.authService.logIn())
    ),
    { dispatch: false }
    );
    @samjulien

    View Slide

  88. logIn$ = createEffect(() =>
    this.actions$.pipe(
    ofType(AuthActions.logIn),
    tap(() => this.authService.logIn())
    ),
    { dispatch: false }
    );
    @samjulien

    View Slide

  89. logIn$ = createEffect(() =>
    this.actions$.pipe(
    ofType(AuthActions.logIn),
    tap(() => this.authService.logIn())
    ),
    { dispatch: false }
    );
    @samjulien

    View Slide

  90. logIn$ = createEffect(() =>
    this.actions$.pipe(
    ofType(AuthActions.logIn),
    tap(() => this.authService.logIn())
    ),
    { dispatch: false }
    );
    @samjulien

    View Slide

  91. logIn$ = createEffect(() =>
    this.actions$.pipe(
    ofType(AuthActions.logIn),
    tap(() => this.authService. )
    ),
    { dispatch: false }
    );
    @samjulien
    logIn()

    View Slide

  92. logIn$ = createEffect(() =>
    this.actions$.pipe(
    ofType(AuthActions.logIn),
    tap(() => this.authService. )
    ),
    { dispatch: false }
    );
    @samjulien
    logIn()

    View Slide

  93. logIn$ = createEffect(() =>
    this.actions$.pipe(
    ofType(AuthActions.logIn),
    tap(() => this.authService. )
    ),
    { dispatch: false }
    );
    @samjulien
    logIn()

    View Slide

  94. export class AuthService {
    // other methods hidden
    logIn() {
    this.authClient.loginWithRedirect();
    }
    }
    @samjulien

    View Slide

  95. export class AuthService {
    // other methods hidden
    logIn() {
    this.authClient.loginWithRedirect();
    }
    }
    @samjulien

    View Slide

  96. logIn$ = createEffect(() =>
    this.actions$.pipe(
    ofType(AuthActions.logIn),
    tap(() => this.authService. )
    ),
    { dispatch: false }
    );
    @samjulien
    logIn()

    View Slide

  97. logIn$ = createEffect(() =>
    this.actions$.pipe(
    ofType(AuthActions.logIn),
    tap(() => this.authService.logIn())
    ),
    { dispatch: false }
    );
    @samjulien

    View Slide

  98. logIn$ = createEffect(() =>
    this.actions$.pipe(
    ofType(AuthActions.logIn),
    tap(() => this.authService.logIn())
    ),
    { dispatch: false }
    );
    @samjulien

    View Slide

  99. logIn$ = createEffect(() =>
    this.actions$.pipe(
    ofType(AuthActions.logIn),
    tap(() => this.authService.logIn())
    ),
    { dispatch: false }
    );
    @samjulien

    View Slide

  100. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects

    View Slide

  101. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects

    View Slide

  102. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects


    View Slide

  103. Effects function as a task runner.
    @samjulien

    View Slide

  104. View Slide

  105. “Hey DJ, play my fave song!”
    @samjulien

    View Slide

  106. “Hey DJ, play my fave song!”
    @samjulien

    View Slide

  107. “Hey DJ, play my fave song!”
    @samjulien
    Grab a record

    View Slide

  108. “Hey DJ, play my fave song!”
    @samjulien
    Grab a record
    Put it on the player

    View Slide

  109. “Hey DJ, play my fave song!”
    @samjulien
    Grab a record
    Put it on the player
    Play the song

    View Slide

  110. “Hey DJ, play my fave song!”
    @samjulien
    Grab a record
    Put it on the player
    Play the song

    View Slide

  111. @samjulien
    “Hey app, log me in!”

    View Slide

  112. “Hey app, log me in!”
    @samjulien

    View Slide

  113. “Hey app, log me in!”
    @samjulien
    Call the auth service to log in

    View Slide

  114. “Hey app, log me in!”
    @samjulien
    Call the auth service to log in
    Handle the redirect flow

    View Slide

  115. “Hey app, log me in!”
    @samjulien
    Call the auth service to log in
    Handle the redirect flow
    Update the store

    View Slide

  116. “Hey app, log me in!”
    @samjulien
    Call the auth service to log in
    Handle the redirect flow
    Update the store

    View Slide

  117. Start login
    Handle redirect
    Log in to provider
    @samjulien

    View Slide

  118. Handle redirect
    Success
    Error
    @samjulien

    View Slide

  119. Success
    User Token
    Redirect
    @samjulien

    View Slide

  120. export const handleRedirect = createAction(
    ‘[Auth] Handle redirect’
    );
    @samjulien

    View Slide

  121. handleRedirect$ = createEffect(() =>
    this.actions$.pipe(
    ofType(AuthActions.handleRedirect),
    exhaustMap(() => {
    @samjulien
    )
    );
    ... })

    View Slide

  122. handleRedirect$ = createEffect(() =>
    this.actions$.pipe(
    ofType(AuthActions.handleRedirect),
    exhaustMap(() => {
    @samjulien
    )
    );
    ... })

    View Slide

  123. handleRedirect$ = createEffect(() =>
    this.actions$.pipe(
    ofType(AuthActions.handleRedirect),
    exhaustMap(() => {
    @samjulien
    )
    );
    ... })

    View Slide

  124. handleRedirect$ = createEffect(() =>
    this.actions$.pipe(
    ofType(AuthActions.handleRedirect),
    exhaustMap(() => {
    @samjulien
    )
    );
    })

    View Slide

  125. handleRedirect$ = createEffect(() =>
    this.actions$.pipe(
    ofType(AuthActions.handleRedirect),
    exhaustMap(() => {
    @samjulien
    )
    );
    ... })

    View Slide

  126. exhaustMap(() => {
    @samjulien
    this.authService.handleRedirect.pipe(
    map(({ payload, redirectUrl }) => {
    // Set the user & token somewhere??
    // Navigate to the redirectUrl??
    return AuthActions.handleRedirectSuccess();
    }),
    catchError(({ error }) =>
    AuthActions.handleRedirectFailure(
    { error }
    ))
    );

    View Slide

  127. exhaustMap(() => {
    @samjulien
    this.authService.handleRedirect.pipe(
    map(({ payload, redirectUrl }) => {
    // Set the user & token somewhere??
    // Navigate to the redirectUrl??
    return AuthActions.handleRedirectSuccess();
    }),
    catchError(({ error }) =>
    AuthActions.handleRedirectFailure(
    { error }
    ))
    );

    View Slide

  128. exhaustMap(() => {
    @samjulien
    this.authService.handleRedirect.pipe(
    map(({ payload, redirectUrl }) => {
    // Set the user & token somewhere??
    // Navigate to the redirectUrl??
    return AuthActions.handleRedirectSuccess();
    }),
    catchError(({ error }) =>
    AuthActions.handleRedirectFailure(
    { error }
    ))
    );
    Calls Auth SDK to get *

    View Slide

  129. exhaustMap(() => {
    @samjulien
    this.authService.handleRedirect.pipe(
    map(({ payload, redirectUrl }) => {
    // Set the user & token somewhere??
    // Navigate to the redirectUrl??
    return AuthActions.handleRedirectSuccess();
    }),
    catchError(({ error }) =>
    AuthActions.handleRedirectFailure(
    { error }
    ))
    );

    View Slide

  130. exhaustMap(() => {
    @samjulien
    this.authService.handleRedirect.pipe(
    map(({ payload, redirectUrl }) => {
    // Set the user & token somewhere??
    // Navigate to the redirectUrl??
    return AuthActions.handleRedirectSuccess();
    }),
    catchError(({ error }) =>
    AuthActions.handleRedirectFailure(
    { error }
    ))
    );

    View Slide

  131. exhaustMap(() => {
    @samjulien
    this.authService.handleRedirect.pipe(
    map(({ payload, redirectUrl }) => {
    // Set the user & token somewhere??
    // Navigate to the redirectUrl??
    return AuthActions.handleRedirectSuccess();
    }),
    catchError(({ error }) =>
    AuthActions.handleRedirectFailure(
    { error }
    ))
    );

    View Slide

  132. exhaustMap(() => {
    @samjulien
    this.authService.handleRedirect.pipe(
    map(({ payload, redirectUrl }) => {
    // Set the user & token somewhere??
    // Navigate to the redirectUrl??
    return AuthActions.handleRedirectSuccess();
    }),
    catchError(({ error }) =>
    AuthActions.handleRedirectFailure(
    { error }
    ))
    );

    View Slide

  133. exhaustMap(() => {
    @samjulien
    this.authService.handleRedirect.pipe(
    map(({ payload, redirectUrl }) => {
    // Set the user & token somewhere??
    // Navigate to the redirectUrl??
    return AuthActions.handleRedirectSuccess();
    }),
    catchError(({ error }) =>
    AuthActions.handleRedirectFailure(
    { error }
    ))
    );

    View Slide

  134. exhaustMap(() => {
    @samjulien
    this.authService.handleRedirect.pipe(
    map(({ payload, redirectUrl }) => {
    // Set the user & token somewhere??
    // Navigate to the redirectUrl??
    return AuthActions.handleRedirectSuccess();
    }),
    catchError(({ error }) =>
    AuthActions.handleRedirectFailure(
    { error }
    ))
    );


    View Slide

  135. exhaustMap(() => {
    @samjulien
    this.authService.handleRedirect.pipe(
    map(({ payload, redirectUrl }) => {
    // Set the user & token somewhere??
    // Navigate to the redirectUrl??
    return AuthActions.handleRedirectSuccess();
    }),
    catchError(({ error }) =>
    AuthActions.handleRedirectFailure(
    { error }
    ))
    );



    View Slide

  136. exhaustMap(() => {
    @samjulien
    this.authService.handleRedirect.pipe(
    map(({ payload, redirectUrl }) => {
    // Set the user & token somewhere??
    // Navigate to the redirectUrl??
    return AuthActions.handleRedirectSuccess();
    }),
    catchError(({ error }) =>
    AuthActions.handleRedirectFailure(
    { error }
    ))
    );

    View Slide

  137. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects

    View Slide

  138. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects

    View Slide

  139. Find the hidden side effect.
    @samjulien

    View Slide

  140. Handle redirect
    Success
    Error
    @samjulien

    View Slide

  141. Success
    User Token
    Redirect
    @samjulien

    View Slide

  142. Break a complex Effect into smaller pieces.
    @samjulien

    View Slide

  143. Let one Effect handle one side effect.
    @samjulien

    View Slide

  144. Handle Redirect Flow
    @samjulien

    View Slide

  145. Handle Redirect Flow
    @samjulien
    Call the auth service to process

    View Slide

  146. Handle Redirect Flow
    @samjulien
    Call the auth service to process
    Update the store

    View Slide

  147. Handle Redirect Flow
    @samjulien
    Call the auth service to process
    Update the store
    Redirect the user

    View Slide

  148. Handle Redirect Flow
    @samjulien
    Call the auth service to process
    Update the store
    Redirect the user

    View Slide

  149. exhaustMap(() => {
    @samjulien
    this.authService.handleRedirect.pipe(
    map(({ payload, redirectUrl }) => {
    // Set the user & token somewhere??
    // Navigate to the redirectUrl??
    return AuthActions.handleRedirectSuccess();
    }),
    catchError(({ error }) =>
    AuthActions.handleRedirectFailure(
    { error }
    ))
    );

    View Slide

  150. exhaustMap(() => {
    @samjulien
    this.authService.handleRedirect.pipe(
    map(({ payload, redirectUrl }) => {
    // Set the user & token somewhere??
    // Navigate to the redirectUrl??
    return AuthActions.handleRedirectSuccess();
    }),
    catchError(({ error }) =>
    AuthActions.handleRedirectFailure(
    { error }
    ))
    );

    View Slide

  151. exhaustMap(() => {
    @samjulien
    this.authService.handleRedirect.pipe(
    map(({ payload, redirectUrl }) => {
    // Set the user & token somewhere??
    // Navigate to the redirectUrl??
    return AuthActions.handleRedirectSuccess();
    }),
    catchError(({ error }) =>
    AuthActions.handleRedirectFailure(
    { error }
    ))
    );

    View Slide

  152. exhaustMap(() => {
    @samjulien
    this.authService.handleRedirect.pipe(
    map(({ payload, redirectUrl }) =>
    AuthActions.handleRedirectSuccess(
    { payload, redirectUrl }
    )),
    catchError(({ error }) =>
    AuthActions.handleRedirectFailure(
    { error }
    ))
    );

    View Slide

  153. @samjulien
    Back to the reducer…

    View Slide

  154. on(AuthActions.handleRedirectSuccess,
    (state, { payload }) => {
    return {
    ...state,
    token: payload.accessToken,
    user: payload.userProfile
    };
    });
    @samjulien

    View Slide

  155. on(AuthActions.handleRedirectSuccess,
    (state, { payload }) => {
    return {
    ...state,
    token: payload.accessToken,
    user: payload.userProfile
    };
    });
    @samjulien

    View Slide

  156. on(AuthActions.handleRedirectSuccess,
    (state, { payload }) => {
    return {
    ...state,
    token: payload.accessToken,
    user: payload.userProfile
    };
    });
    @samjulien

    View Slide

  157. @samjulien
    …and then create a new Effect.

    View Slide

  158. handleRedirectSuccess$ = createEffect(
    () =>
    this.actions$.pipe(
    ofType(AuthActions.handleRedirectSuccess),
    tap(({ redirectUrl }) =>
    this.router.navigate([redirectUrl]))
    ),
    { dispatch: false }
    );
    @samjulien

    View Slide

  159. handleRedirectSuccess$ = createEffect(
    () =>
    this.actions$.pipe(
    ofType(AuthActions.handleRedirectSuccess),
    tap(({ redirectUrl }) =>
    this.router.navigate([redirectUrl]))
    ),
    { dispatch: false }
    );
    @samjulien

    View Slide

  160. handleRedirectSuccess$ = createEffect(
    () =>
    this.actions$.pipe(
    ofType(AuthActions.handleRedirectSuccess),
    tap(({ redirectUrl }) =>
    this.router.navigate([redirectUrl]))
    ),
    { dispatch: false }
    );
    @samjulien

    View Slide

  161. handleRedirectSuccess$ = createEffect(
    () =>
    this.actions$.pipe(
    ofType(AuthActions.handleRedirectSuccess),
    tap(({ redirectUrl }) =>
    this.router.navigate([redirectUrl]))
    ),
    { dispatch: false }
    );
    @samjulien

    View Slide

  162. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects



    View Slide

  163. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects




    View Slide

  164. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects





    View Slide

  165. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects






    View Slide

  166. Let’s Review

    View Slide

  167. Effects are one of the hardest
    parts of learning NgRx.
    @samjulien

    View Slide

  168. Effects are a huge part of
    implementing auth in NgRx.
    @samjulien

    View Slide

  169. @samjulien

    View Slide

  170. Auth Service
    Components
    Data Services
    @samjulien

    View Slide

  171. @samjulien

    View Slide

  172. Reducers
    Components
    Effects
    Auth Service
    @samjulien

    View Slide

  173. Effects
    @samjulien

    View Slide

  174. Effects
    @samjulien
    Decide when to call services

    View Slide

  175. Effects
    @samjulien
    Decide when to call services
    Communicate with APIs

    View Slide

  176. Effects
    @samjulien
    Handle control flow logic
    Decide when to call services
    Communicate with APIs

    View Slide

  177. View Slide

  178. Effects: The Struggle
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects

    View Slide

  179. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects



    View Slide

  180. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects



    View Slide

  181. Start login
    Log in to provider
    @samjulien

    View Slide

  182. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects

    View Slide

  183. Effects function as a task runner.
    @samjulien

    View Slide

  184. “Hey app, log me in!”
    @samjulien
    Call the auth service to log in
    Handle the redirect flow
    Update the store

    View Slide

  185. Handle redirect
    Success
    Error
    @samjulien

    View Slide

  186. Success
    User Token
    Redirect
    @samjulien

    View Slide

  187. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects

    View Slide

  188. Find the hidden side effect.
    @samjulien

    View Slide

  189. Break a complex Effect into smaller pieces.
    @samjulien

    View Slide

  190. Let one Effect handle one side effect.
    @samjulien

    View Slide

  191. Handle Redirect Flow
    @samjulien
    Call the auth service to process
    Update the store
    Redirect the user

    View Slide

  192. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects



    View Slide

  193. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects




    View Slide

  194. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects





    View Slide

  195. Effects in NgRx Auth
    @samjulien
    Actions that only trigger Effects
    Non-dispatching Effects
    Writing complex Effects






    View Slide

  196. View Slide

  197. View Slide

  198. View Slide

  199. View Slide

  200. @samjulien
    NgRx Conf
    November 5-6, 2020
    U.S. Space & Rocket Center, Huntsville, AL
    https://ti.to/ngrx-conf/2020/discount/ngconf

    View Slide

  201. samj.im/ngconf-hardwired
    @samjulien

    View Slide

  202. samj.im/ngconf-hardwired
    Thank you!
    @samjulien

    View Slide