Search code examples
angularangular6rxjs6ngxs

Angular/NGXS sample code - cannot get reference of the parameter input


I'm trying to implement the login as mentioned here.

https://ngxs.gitbook.io/ngxs/recipes/authentication

  @Action(Login)
  login({ patchState }: StateContext<AuthStateModel>, { payload: { username } }: Login) {
    return this.authService.login(payload).pipe(tap((result: { token: string }) => {
      patchState({ token, username });
    }))
  }

But I'm unable to get the reference of 'payload' as shown in the sample, instead I get the following error. Any help appreciated ! I also wanted to know what '{ payload: { username } }' would mean in the input parameters of the function.

enter image description here


Solution

  • This is an error in the documentation.

    Look here:

    export class Login {
      static readonly type = '[Auth] Login';
      constructor(public payload: { username: string, password: string }) {}
    }
    

    and here:

    login({ patchState }: StateContext<AuthStateModel>, { payload: { username } }: Login) {
    

    This is a destructure mistake and needs to be:

    @Action(Login)
    login({ patchState }: StateContext<AuthStateModel>, { payload }: Login) {
      return this.authService.login(payload).pipe(tap((result: { token: string }) => {
        patchState({ token, username: payload.username });
      }))
    }
    

    This destructures Login's payload and then reference username via payload.username.

    Credentials are sent upstream and a token is returned downstream. The AuthStateModel is patched via the StateContext.

    Git Blame authentication.md

    What Is Destructuring?

    { payload: { username } } is Destructuring assignment . In the context of a function parameter, it means, "in this object, I am interested in these properties." Looking at login(), it means, "I am only interested in username (which is wrong as state above).

    I hope this helps!

    UPDATE:

    This fix has been merged in #653.

    Just to clarify:

    let a = { payload: { username: { first: 'rafael', last: 'cepeda' } } };
    let { payload: { username } } = a;//unwraps payload.username
    console.log(username);//works
    console.log(payload);//error

    Fix:

    let a = { payload: { username: { first: 'rafael', last: 'cepeda' } } };
    let { payload } = a;//unwraps payload
    console.log(payload.username);//works
    console.log(payload);//works