0

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.

2
  • Based on the comments in your code, it sounds like you want to subscribe to an elements attribute. Is that correct? Commented Nov 18, 2019 at 16:24
  • @robbieAreBest yes, i want to subscribe to scrollHeight property so i can set it to scrollTop in order to scroll to bottom when a new content is added to the element Commented Nov 18, 2019 at 18:57

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks. a question though, when would the second approach using component be better than using ChangeDetectorRef? or it's just our preference?
IMO, if you can avoid using cdr without making too much effort, then put away cdr. In this case I'd go with the second approach as this will allow to encapsulate the logic. For example, a parent of such component might only be interested in a few properties from the child, and computation logic can take place in the child, without adding unrelated code to the parent.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.