Angular 6: OnChanges does not work with async pipe

b0bi

I have a component that needs to track changes to the data source. The parent component provides data via async pipe. If the data source is changed (item added or deleted), then ngOnChanges does not fires.

Help to deal with the problem.

@Component({
  selector: 'app-todo',
  template: `
<div>
  <button (click)="addTodo()">Add Item</button><br />

    <div *ngFor="let todo of todos">
        {{ todo.value }} <button (click)="deleteTodo(todo.id)">x</button>
    </div>
</div>
`
})
export class TodoComponent implements OnChanges {
  @Input() todos: Todo[];

  constructor(private todoService: TodoService) {
  }

  addTodo() {
    this.todoService.create({ value: 'value '+this.todos.length });
  }

  ngOnChanges(changes: { [key: string]: SimpleChange })
  {
    if (changes['todos']) { 
      console.log('todos changed')
    }
  }

  deleteTodo(todoId: number) {
    this.todoService.remove(todoId);
  }
}

Parent component:

@Component({
  selector: 'my-app',
  template: `
<h1>Angular Observable Data Services</h1>

<p>Only implimented a simple post and delete</p>

<h3>Component 1</h3>
<app-todo [todos]='todos | async'></app-todo>

<br /><br />

<h3>Component 2</h3>
<app-todo [todos]='todos | async'></app-todo>
`
})
export class AppComponent  {
  todos: Observable<Todo[]>;

  constructor(private todoService: TodoService){
    this.todos = this.todoService.todos;

    this.todoService.loadAll();
  }
}

stackblitz

dee zg

You're hitting shallow/deep clone problem.

For example, in your service create method you copy this.dataStore but then you reuse its todos property which is not copied, it stays the same reference thus there is nothing to trigger onChange.

what you want to do is something like:

this.dataStore.todos.push(something); //this mutates an array
const x = [...this.dataStore.todos];`//clones actual array

and feed that into your BehaviorSubject.next(x)

useful ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Deep_Clone

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related