2
votes

I have a Component-directive that I use to show a div with some information.

This component is called SitesComponent and is included in a page. The main behavior of the SitesComponent is fine, except for this:

  • I have an API call to a backend where I return some data, the backend call is executed well and I received the information but the variable is not updated on the template

This is my code:

import { Component } from '@angular/core';
import { MyApi } from '../../myapi';

@Component({
  selector: 'sites-component-widget',
  templateUrl: './sites-component.html',
  styleUrls: ['./sites-component.scss'],
})
export class SitesComponent {
    data: any = [];
    constructor(private api: MyApi}

    ngOnInit() {
        var _ = this
          this.api.company_sites(this.companyId).subscribe(
            response => {
                //this.data = response; 
                this.data = [1,2,3]; 
            },
            error => {
              console.log("error")
            }
          )
        }        
    }
}

I tried to update the variable data using the received response and also using static data. The UI is never updated with the changes inside the API call.

I'm using angular http client:

import { HttpClient } from "@angular/common/http";

But it didn't work neither

  • What I'm doing wrong ?

I read about using observables or promises for the API, I tried both ways and I couldn't find a solution... My UI is never updated when I update the variable inside the .subscribe() or .then() functions

EDIT: I forgot to add my html, but as far it is just 3 lines:

<div class="sites-online-widget">
    **{{data}}**
</div>

Summary of my issue:

If I do this the variable is updated on the template

ngOnInit() {
    this.data = [1,2,3,4]
}

but when I do this, the variable is not updated on the template:

ngOnInit() {
    var _ = this
      this.api.company_sites(this.companyId).subscribe(
        response => {
            this.data = [1,2,3]; 
        }
      )}        
}

Final Edit

Found a solution that worked in another question, I tried to close this one.

The question that solved my issue was this:

Angular 2 View will not update after variable change in subscribe

3 basic steps:

// Import ChangeDetectorRef
import { ChangeDetectorRef } from '@angular/core';

// Add ChangeDetectorRef to constructor
constructor(private cd: ChangeDetectorRef) {}

// Call markForCheck at the end of the subscribe function
this.cd.markForCheck();

My code ended like:

import { Component } from '@angular/core';
import { MyApi } from '../../myapi';

// 1
import { ChangeDetectorRef } from '@angular/core';

@Component({
  selector: 'sites-component-widget',
  templateUrl: './sites-component.html',
  styleUrls: ['./sites-component.scss'],
})
export class SitesComponent {
    data: any = [];
    constructor(
      private api: MyApi,
      // 2
      private cd: ChangeDetectorRef}

    ngOnInit() {
        var _ = this
          this.api.company_sites(this.companyId).subscribe(
            response => {
                this.data = response; 
                // 3
                this.cd.markForCheck()
            },
            error => {
              console.log("error")
            }
          )
        }        
    }
}
1
can you post your html - LLai
@Llai yes, I forgot to add it but right now I'm just showing the value inside the variable - AlvaroAV
can you do an ngif ? Show the div if the data is not null or something? - Bhavik Patel
I did, data is initialized to empty array []. If I do ngIf to show if data is empty, it is, even after receiving the response. Like I said, it seems the main issue is that the variable data is not being updated inside the susbcribe method. And I'm 100% sure the code goes inside the subscribe method because I'm printing the result of the API - AlvaroAV
The main issue is the value does not updating in your html. You have the array initialized as [] so your html is rendering an empty array. So do an ngif to show your div only when the array is NOT empty. - Bhavik Patel

1 Answers

1
votes

implement OnInit

import { OnInit } from '@angular/core';

export class SitesComponent implements OnInit {}