Behaviour subject does not update on change Async Angular 10

555 views Asked by At

I have an Observable list that I show in my component. But when I update the list through my backend, the list does not update async in my component view..

My service (where the list is stored):

    export class GameService {
      games: Game[] = []
      public gameSubject = new BehaviorSubject<Game[]>(this.games);
      public readonly games$ = this.gameSubject.asObservable();
    
      constructor(private http: HttpClient) {
        this.getAllGames().subscribe(response => this.gameSubject.next(response))
       }
    
      public createGame(game: Game): Observable<Game> {
        const url = 'http://localhost:8080/api/games';
        return this.http.post<Game>(url, game);
      }
    
      public createAndUpdate(game: Game): void { 
        this.createGame(game).subscribe();
        this.getAllGames().subscribe(response => this.gameSubject.next(response))
    
      }
    
      public getGame(id: number): Observable<Game> {
        const url = 'http://localhost:8080/api/games/sessieId' + id;
        return this.http.get<Game>(url);
      }
    
      public getAllGames(): Observable<Game[]> {
        const url = 'http://localhost:8080/api/games';
        return this.http.get<Game[]>(url);
      }
    
    }

The component (where I display the list)

     <div fxLayout="column" fxLayoutAlign="center center">
              <ng-template ngFor let-j="index" let-playerA [ngForOf]="gameService.games$ | async">
                <div fxFlex fxLayout="row" *ngIf="j % 3 == 0">
                  <ng-template ngFor let-i="index" let-player [ngForOf]="gameService.games$ | async">
                    <div fxFlex *ngIf="i < j + 3 && i >= j">
                      <mat-card class="player-card">
                        <mat-card-header>   
                          <mat-card-title>{{ player.user }}</mat-card-title>
                        </mat-card-header>
                        <mat-card-content>
                          <img src="assets/pictures/man.png" />
                        </mat-card-content>
                      </mat-card>
                    </div>
                  </ng-template>
                </div>
              </ng-template>
            </div>

I call this method when updating the list (creating a new item) (method from service):

    public createAndUpdate(game: Game): void { 
        this.createGame(game).subscribe();
        this.getAllGames().subscribe(response => this.gameSubject.next(response))
    
      }

But I still need to refresh the page to see the changes

1

There are 1 answers

0
user1 On

You have to call this.getAllGames() after this.createGame(game) has finished in order to get the updated list. So you will have to put it inside the this.createGame(game).subscribe(() => this.getAllGames().subscribe(response => this.gameSubject.next(response))) but that looks way too ugly. The proper way would be something like

this.createGame(game).pipe(switchMap(() => this.getAllGames())).subscribe(this.gameSubject)

Which would send the create game request, wait until the game is created on the backend and a response is sent back to the front end and then we make a request to get all the games and push them to the subject.