angularsubjectsubject-observer

Angular – edit/remove element in a Subject Array


I have a Subject of Array of Users

  private _currentHeroes = new Subject<Hero[]>();
  currentHeroes = this._currentHeroes.asObservable();

Function of power up the user in my service

powerUp(id: number) {
return this.http
  .post<Hero>(environment.apiUrl + 'heroes/powerUp/' + id, {})
  .pipe(
    tap((updatedHero: Hero) => {
      this._currentHeroes.next(
        // I would like to edit the specific element in the array and than sort them by the power.
      );
    })
  );
  }

Function of delete the user in my service

  delete(id: number) {
return this.http.delete<Hero>(environment.apiUrl + 'heroes/' + id).pipe(
  tap((deletedHero) => {
    this._currentHeroes.next(
      // Here I delete the specific element from the array
    );
  })
);
  }

If the Subject was BehaviorSubject so I would do this:

    powerUp(id: number) {
    return this.http
      .post<Hero>(environment.apiUrl + 'heroes/powerUp/' + id, {})
      .pipe(
        tap((updatedHero: Hero) => {
          this._currentHeroes.next(
            this._currentHeroes.value
              .map((hero: Hero) =>
                hero.id === updatedHero.id ? updatedHero : hero
              )
              .sort((a, b) => a.currentPower - b.currentPower)
          );
        })
      );
  }

  delete(id: number) {
    return this.http.delete<Hero>(environment.apiUrl + 'heroes/' + id).pipe(
      tap((deletedHero) => {
        this._currentHeroes.next(
          this._currentHeroes.value.filter(
            (hero: Hero) => hero.id !== deletedHero.id
          )
        );
      })
    );
  }

But my goal is to achieve the same while using Subject instead of BehaviorSubject.

I tried getting the value of the subject but it's not possible since it's a Subject. I tried searching online but unfortunately, I didn't find any useful solution for my needs.

Does anyone encounter this issue? Or how to fix it?


Solution

  • I suppose you are working on a service, then you can have a reference of array you need to modify in service attr.

    heroes = [];
    

    then, after every operation, you can modify that values and then emit with Subject or Behavior Subject or whatever you want to use.

    powerUp(id: number) {
    return this.http
      .post<Hero>(environment.apiUrl + 'heroes/powerUp/' + id, {})
      .pipe(
        tap((updatedHero: Hero) => {
            //modify data reference, to add, update or delete value
            // in this case modify with powerup
            this.heroes = this.heroes
                  .map((hero: Hero) =>
                    hero.id === updatedHero.id ? updatedHero : hero
                  )
                  .sort((a, b) => a.currentPower - b.currentPower)
          // emit the resuelt after every operation 
          this._currentHeroes.next(
            this.herores
          );
        })
      );
      }
    

    Remember you have to subscribe to every operation that return an observable like you show in your code.

    // for example to hero with id 2
    this.yourHeroService.powerUp(2).subscribe()