Search code examples
angularangular2-databinding

How to access updated element after changing it using one way binding


I want to update content of a div using string interpolation and then access some properties of that div element immediately. how do i access an updated element?

In the below code snippet, how do i access updated properties of div element in someEventOccurred() method?

Here is my component.js file (stackblitz app)

import { Component, OnInit, ViewChild } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `<div #message>{{ data }}</div>`
})
export class AppComponent  {
  data = 'default';
  @ViewChild('message', {static: false}) message;

  ngOnInit() {
    setTimeout(() => {
      this.someEventOccurred();
    }, 1000);
  }

  someEventOccurred() {
    this.data = 'hello world';

    // how to run something here only after #message is updated
    console.log(this.message.nativeElement.innerText);

    setTimeout(() => {
      // this runs after 1 second, meanwhile view has been updated
      console.log(this.message.nativeElement.innerText);
    }, 1000);
  }
}

I know i can access the updated element in ngAfterViewChecked(), but how would i know which element has changed? I also want to know if there is any other solution than using this hook.

Note: the above code snippet is just an example, in my real project, i'll be calling someEventOccurred() when i get an http response from a remote server. innerText is also just an example, i'll be using different properties of an element.


Solution

  • In order to access the updated properties immediately, instead of using setTimeout, you can manually trigger change detection.

    constructor (private cdr: ChangeDetectorRef) { }
    
    someEventOccurred () {
       this.data = 'hello world';
    
       this.cdr.detectChanges();
    
       console.log(this.message.nativeElement.innerText); // hello world
    }
    

    You might also find this article about change detection useful.

    Another approach that shouldn't involve the ChangeDetectorRef API would be use a component and pass data as @Input params. This way, you can opt for the OnPush detection strategy for that component and emit events(through @Output properties) after computation has been done internally. You can detect changes of @Input properties in the OnChanges lifecycle hook.