Async function not working as intended when called at onInit lifecycle hook

0 votes
asked Sep 13, 2017 by ivan-bespalov

In my project I have a service that should load local database when the app is started. For that the function GetData() is used. I try to use it by calling at the ngOnInit() lifecycle hook. It logs the result in the console, but the property datum appears to be unchanged.

However, if I add GetData() method to a button, the property changes and data is displayed in the console as intended.

All sources that I looked through suggest that the right way to load the DB if I need it right away is to use ngOnInit() hook, that's why I don't wat to call GetData() when some event from the DOM is fired.

Component

export class AppComponent implements OnInit {
  datum;
  constructor(private searchService: SearchService){ }
  getData(){
    this.searchService.getData().subscribe(
      data => {
        this.datum = data[0];
        console.log(this.datum);},
      err => console.log("E", err)
    );
  }

  ngOnInit(){
    this.getData();
  }
  title = 'app';
}

HTML

<div style="text-align:center">
  <h1>
    Welcome to {{title}}!!
    Data: {{datum | json}}
  </h1>
  <button (click)="getData()">Click Me</button>

App loaded

enter image description here

Button clicked

enter image description here

EDIT Implementation of getData() with setTimeout() as suggested by AlexKhymenko

  getData(){
    this.searchService.getData().subscribe(
      data => {
        setTimeout(() =>{
          this.datum = data[0];
        });
        console.log(this.datum);},
      err => console.log("E", err)
    );
  }

3 Answers

0 votes
answered Sep 13, 2017 by manfice

Because in subscribe function you get an observable object (not array).

export class AppComponent implements OnInit {
   datum;
   constructor(private searchService: SearchService){ }
   getData(){
this.searchService.getData().subscribe(
  data => {
    //remove brackets
    this.datum = data;
    console.log(this.datum);},
  err => console.log("E", err)
 );
}

ngOnInit(){
   this.getData();
}
title = 'app';
}
0 votes
answered Sep 13, 2017 by ashish-kadam

Try in HTML

<h1 *ngIf="datum !== null && datum !== undefined && datum !== ''">
Welcome to {{title}}!!
Data: {{datum | json}}
</h1>

Your datum variable was bind two-way data binding. When datum was not equal null or undefined or blank that time show that HTML tag.

Hope that help you.

0 votes
answered Sep 13, 2017 by alexkhymenko

Good Day. What You need to do is to run change Detection manually for example by calling setTimeout. Created plunker

export class AppComponent implements OnInit {
  datum;
  title = 'app';

  constructor(private searchService: SearchService){ }
       }

 ngOnInit(){
   this.getData();
 }
  getData(){
      this.searchService.getData().subscribe(
  data => {
   setTimeout(() => {
            this.datum = data[0];
   })
    console.log(this.datum);},
  err => console.log("E", err)
);

}

Hope this helps. Have a Great Day.

Welcome to Q&A, where you can ask questions and receive answers from other members of the community.
Website Online Counter

...