Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NGXS @Select usage with state model

When using an NGXS @Select decorator what is the right way to access properties defined on the state model.

E.g with the following state defined:

export interface UserStateModel {
 firstname: string;
 lastname: string;
}

@State<UserStateModel>({
  name: 'user',
  defaults: {}
})
export class UserState {..}

In a component if I want to select the user state like this:

..export class MyComponent {

  @Select(UserState) user$: Observable<UserState>;

   ngOnInit(){
     this.user$.subscribe(u => {
         //do something with user state
         console.log(u.firstname);
     });
   }   
}

I get typescript errors as the firstname property doesn't exist on UserState (as it's defined on the related model type). If I'm referencing the property in the component html template then I don't have any issue.

There is a related discussion around selector usage but I just want to confirm what I should expect with the current version (and if I'm doing this correctly!).

I'm using "@ngxs/store": "^3.0.0-rc.2",

like image 472
Garth Mason Avatar asked Nov 30 '22 14:11

Garth Mason


2 Answers

The observable decorated by the @Select decorator will be of the model's data type and not the state class. ie:

export class MyComponent {

  @Select(UserState) user$: Observable<UserStateModel>;

   ngOnInit(){
     this.user$.subscribe(u => {
         //do something with user state
         console.log(u.firstname);
     });
   }   
}

Another note is that I recommend the use of the async pipe in your template so that Angular manages the subscription and unsubscription for you.

like image 110
Mark Whitfeld Avatar answered Dec 04 '22 02:12

Mark Whitfeld


Take a look at this runnable demo project I just created.

It provides a demo to select allBooks$ and thickBooks$ from a BookStateModel that contains books: Book[].

Things to note:

  • @Selector() is declared (memoized) in BookState.ts so that it can be used elsewhere.
  • These memoized selectors can be used via @Select(Xxx).

Hope this helps.

like image 23
kctang Avatar answered Dec 04 '22 03:12

kctang