0

here's the code:

async ngOnInit() {
    @Select(UserPageState.get('collection')) users$: BehaviorSubject<Array<Partial<User>>>;


    const USER = this.creds.credentials['id'];
    this.users$.subscribe(param => this.users$.next(param.filter(x => x.id !== USER)));

    await this.store.dispatch(new UserPageList({ start: 1, length: this.pageSize })).toPromise();
    }

ERROR

ERROR TypeError: _this.users$.next is not a function
    at SafeSubscriber._next

user.ts

  username: string;
  password?: string;
  token: string;
  avatar: string;
  firstName: string;
  lastName: string;
  email: string;
  department: string;
  position: string;
  role: string;
  status: string;
  enabled: boolean;
  groups: Array<Group>;
  location: Array<Sbu>;

every time i run the application the error is always next is not a function. and i tried to change the behavioursubject to BehaviorSubject(Array>);

and all my code is error.

Panda
  • 365
  • 9
  • 23
  • What's `@Select(UserPageState.get('collection'))`? – Kurt Hamilton Mar 16 '20 at 10:59
  • 3
    And where is `users$` being set? And won't this cause a stack overflow if you are emitting a value into a subject from within that subject's subscription? – Kurt Hamilton Mar 16 '20 at 11:00
  • @KurtHamilton clearly some design flaws here :D. I don't know what `@Select` is, but clearly not an Angular annotation – Guerric P Mar 16 '20 at 11:01
  • 1. BehaviorSubject needs to be initialized with an initial value. 2. It is better to replace `this.users$.subscribe` with `this.users$.asObservable().subscribe`. 3. As others have mentioned, there is a fundamental flaw here. Subscribing to an observable and updating it within itself creates a cyclic lock and will lead to error. – ruth Mar 16 '20 at 11:05
  • @Michael D, Please clarify why you suggest using `asObservable()` here. – mamichels Mar 16 '20 at 11:10
  • @KurtHamilto I used statement – Panda Mar 16 '20 at 11:18
  • `"and i tried to change the behavioursubject to BehaviorSubject(Array>);"` Note that changing the type declarations in typescript won't affect the types of the values in runtime. Types in typescript is just a tool to help you at compile time – ShamPooSham Mar 16 '20 at 11:20
  • @mamichels: please see [here](https://stackoverflow.com/a/36989035/6513921). – ruth Mar 16 '20 at 11:24

2 Answers2

2

It seems you're using Ngxs library for state management, with its Select decorator to retrieve a slice of state.

@Select returns simple observable, and not BehaviorSubject. Your declaration should be :

@Select(UserPageState.get('collection')) users$: Observable<User[]>;

or with Partial<User>[], but I don't have details of your implementation

So If you just want to filter users retrieved by this selector:

export class YourComponent {
  @Select(UserPageState.get('collection')) users$: Observable<User[]>;
  filteredUsers$: Observable<User[]>;

  ngOnInit() {
    const USER = this.creds.credentials['id'];
    this.filteredUsers = this.users$.pipe(
      map(users => users.filter(user => user.id !== USER))
    );

    this.store.dispatch(new UserPageList({ start: 1, length: this.pageSize }));
  }
}

in your template:

  <ul>
    <li *ngFor="let user of filteredUsers$ | async">
      {{ user.name }}
    </li>
  </ul>

Note that you should probably consider to create a dedicated selector and add USER in your store too.

Thierry Falvo
  • 5,892
  • 2
  • 21
  • 39
  • where do I put the ```await this.store.dispatch(new UserPageList({ start: 1, length: this.pageSize })).toPromise();``` – Panda Mar 16 '20 at 11:51
  • 2
    I've updated my answer because I think I better understand your issue. But I recommend you to read [https://www.ngxs.io/](ngxs docs) and also [https://angular.io/guide/observables-in-angular](Observables in Angular). – Thierry Falvo Mar 16 '20 at 13:18
0

Try like this. It may be work import { of, Subject, Observable } from 'rxjs';

  private users$= new Subject<void>();
 onusers$: Observable<void>;


 this.onusers$ = this.users$.asObservable();


   this.users$.next(param:{param.filter(x => x.id !== USER))});