Search code examples
angularstate-managementngxs

read data NGXS Angular


i Am Making Authentication Using NGXS.. I am Trying to get Current User Data after Login and put it in the state to read it in homepage such as (username , email and userType)

my state function is working and set the new values in the state but i cant read it from home page after login

maybe the way that i am using to get current user data wrong

so i need to read the username and email that stored in GetCurrentUser State

My auth.state.ts file

export class AuthStateModel {
  token: string;
  email: string;
  user_name: string;
}
@State<AuthStateModel>({
  name: "auth",
  defaults: {
    token: null,
    email: null,
    user_name: null,
  },
})
export class AuthState {
  @Selector()
  static currentUser(state: AuthStateModel) {
    return {
      email: state.email,
      user_name: state.user_name,
    };
  }
  constructor(private authService: AuthService) {}
  @Action(GetCurrentUser)
  getcurrentUser(ctx: StateContext<AuthStateModel>) {
    return this.authService.getCurrentUser().pipe(
      tap((x: any) => {
        const state = ctx.getState();
        ctx.patchState({
          email: x.email,
          user_name: x.user_name,
        });
      })
    );
  }
}

NGX-logger-plugin from inspect element

next state {auth: {…}}auth: {token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJod…hYSJ9.nwYZyOmIVLLGx_1FvmrQ-u--6fp0nVphwRfNyE14Xsc", email: "asd@asd.com", user_name: "hsss"}

My CompanyhomeComponent.ts file

@Component({
  selector: "kt-companyhome",
  templateUrl: "./companyhome.component.html",
  styleUrls: ["./companyhome.component.scss"],
})
export class CompanyhomeComponent implements OnInit {
  constructor(private store: Store) {}

  ngOnInit(): void {
    this.store.dispatch(new GetCurrentUser());
  }
}

Now how can i read it in CompanyhomeComponent.html i tried a lot of ways but nothing working


Solution

  • Your component needs to select the value from the store. Since you have a @Selector defined, you can use that:

    @Select(AuthState.currentUser) user$: Observable<any>;
    

    or you can use store.select with the selector:

    user$: Observable<any> = this.store.select(AuthState.currentUser);
    

    or without:

    user$: Observable<any> = this.store.select((state) => {
      return {
        email: state.email,
        user_name: state.user_name,
    });
    

    Then in your template you can use the async pipe:

    <div *ngIf="user$ | async; let user">
      <span>{{ user.email }}</span>
      <span>{{ user.user_name }}</span>
    </div>
    

    Side note: since you're returning an object with email and user_name, but not token, to avoid using any, you'd have to either declare it as an anonymous type:

    Observable<{email:string; user_name: string}>
    

    or use Partial:

    Observable<Partial<AuthStateModel>>