0

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

prawwe316
  • 225
  • 1
  • 6
  • 17

1 Answers1

1

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.

Samarpan
  • 913
  • 5
  • 12
  • this works. But there seems to be some issue. If there is a pagination, and suppose i am on the 3rd page, the list jumps pack to page one after updating. What might be causing this issue? https://angular-boenjx.stackblitz.io – prawwe316 Apr 24 '19 at 17:11
  • here is the fork with pagination added https://stackblitz.com/edit/angular-boenjx – prawwe316 Apr 24 '19 at 17:19
  • fixed the issue in your stackblitz. Take a look. Just updated your subscribe handler in child2.component.ts – Samarpan Apr 25 '19 at 08:44
  • i am not able to find the change. can you help me out? Thanks – prawwe316 Apr 25 '19 at 10:24
  • In child2.component.ts, replace - this.todos$.subscribe( (data)=>{ this.page = this.page || 1; this.pageSize = 10; } ) - https://stackblitz.com/edit/angular-boenjx – Samarpan Apr 25 '19 at 12:16
  • the issue still exists. if you open any todo from page >1 , after modal open it resets to page 1 – prawwe316 Apr 25 '19 at 16:57
  • what i could probably do is if i receive success in patch request, then i will have to reassign this.page to what it was before the request was sent – prawwe316 Apr 25 '19 at 17:01
  • Did you use the fix I shared. You need to update statement which is currently - this.page = 1; Change this to - this.page = this.page || 1; That is the fix to your issue. I have done that change but it seems it gets reverted when share it with you. Let me update my answer as well. – Samarpan Apr 26 '19 at 06:06
  • this worked!! I had created a behaviour subject.. and let currentPage = this.page after getting patch response as success, i set this.page = currentPage The solution you gave is way more simple. thanks!! @samy-b – prawwe316 Apr 27 '19 at 09:25