prawwe316
prawwe316

Reputation: 255

How to update a behaviour subject after patch request?

How to update the view with new values after making a patch request?

I have created a dummy app on stackblitz. https://stackblitz.com/edit/angular-j35vrb

On clicking any row from the table, a modal opens and status of the TODO is updated. If the status is incomplete = false, patch request is sent and status is updated to true (can be seen in the console log).

How do i inform the behaviourSubject (through which data is being fetched) that there is some update in the content? so that the table as well as the top section (No. of complete/incomplete Todos) shows updated values

Upvotes: 0

Views: 1616

Answers (1)

Samarpan
Samarpan

Reputation: 943

I have updated your stackblitz with solution. Here is what you need to do.

In main.service.ts,

Keep a reference of todos within the service itself for future updates. See below.

private allTodos: Todo[];

  getTodo() {
    if(!this.allTodos$){
      this.allTodos$ = <BehaviorSubject<Todo[]>>new BehaviorSubject(new Array<Todo>());
      this.http
        .get<Todo[]>(
          'https://jsonplaceholder.typicode.com/todos'
      ).subscribe(
          (data: Todo[]) => {
            this.allTodos = data;
            this.allTodos$.next(data);
          }
        ),
        error => console.log(error);
    }    
  }

Return the BehaviourSubject directly from subscribetoTodos method. Subjects can be subscribed directly.

subscribetoTodos(): Observable<Todo[]>{
    return this.allTodos$;
  }

update 'updateToDo' method as below. Notice how I am updating one reference of Todo in the list here and sending it to subscribers via next.

updateTodo(id){
    this.http.patch('https://jsonplaceholder.typicode.com/todos/' + id , { 'completed': true })
    .subscribe(
      data => {
        this.allTodos.find(todo => {
          if (todo.id === id) {
            Object.assign(todo, data);
            return true;
          }
          return false;
        });
        console.log(data);
        this.allTodos$.next(Object.assign([], this.allTodos));
      },
      error => console.log(error)
    )
  }

This will update your view.

In case of paginated data, change the subscription to the below.

ngOnInit() {
    this.todos$ = this.mainService.subscribetoTodos();
    this.todos$.subscribe(
      (data)=>{
      this.page = this.page || 1;
      this.pageSize = 10;
      }
    )
  }

Notice how I am checking if this.page exist, then use that, else go to page 1.

this.page = this.page || 1;

Earlier it was,

this.page = 1;

which was resetting the page back to 1 whenever any update happened.

Upvotes: 1

Related Questions