0

Here is my main component.

<div *ngIf="user$ | async">
  <h1>test</h1>
</div>
@Component({
  selector: 'app-core',
  templateUrl: './core.component.html',
  styleUrls: ['./core.component.scss']
})
export class CoreComponent {
  @Select(UserState) public user$!: Observable<User>;
  constructor() {}
}

And I wrote UserState, with ngxs.

@State<UserStateModel>({
  name: 'user',
})
@Injectable()
export class UserState {
  constructor(
    private api: ApiService,
    private tokens: TokenService) { }

  @Action(GetUser)
  public get(ctx: StateContext<UserStateModel>) {
    const id = this.tokens.getAccessTokenPayload()!.sub;
    return this.api.get<User>(Endpoint.USERS, id).pipe(
      tap((user: User) => {
        ctx.setState(user);
      })
    );
  }
}

Why the condition of my *ngIf is ignored and the router-outlet is rendered when I haven't even initialized the value of my user state.

With ReduxDevtool

With Redux Devtool

Update after Michaël answer

<div *ngIf="user">
  <h1>test</h1>
</div>
@Component({
  selector: 'app-core',
  templateUrl: './core.component.html',
  styleUrls: ['./core.component.scss']
})
export class CoreComponent implements OnInit {
  public user?: User;
  constructor() {}
  public ngOnInit(){
    this.store.select(UserState).subscribe((user) => {
      this.user = user;
    });
  }
}

For testing purposes, I tried this, and the user state is still initialized. I don't understand why.

Julien LeGa
  • 55
  • 2
  • 6

1 Answers1

0

According to NGXS documentation :

By adding the definite assignment assertion we're telling the type-checker that we're sure that pandas$ property will be initialized (by the @Select decorator).

So the fact you are using both @Select AND Definite Assignment Assertion causes your user$ to be initialized.

  • I tried some change (I update my question above), and the user state is still initialized. I don't understand why. – Julien LeGa Sep 06 '22 at 16:43