0

I have a weird bug in my angular project. When I fetch my data with a mock API from local data, everything is working fine, but when I switch to Online API and fetch data with Observable subscribe method, data is not updated in my angular template view. It will be updated only when I call detector.detectChanges() method.

In brief, For somehow when using online API, two-way data binding is only working when I call detectChanges.

For example imagine below scenario:

 data = [some data here...]
 getData(): Observable<any> {
    return of(this.data);
}

when I call this method in my .ts file and fetch data with it, angular template will be updated automatically. But when i switch to below code:

getData(): Observable<any> {
    let url = `${this.API_URL}/fetchData/`;
    return this.http.get(url);
}

and fetch data in my angular .ts file like below:

this.myService.getData().subscribe(result => {
    this.myData = result;
    // this.detector.detectChanges();
})

myData variable is not updated in the angular template unless I uncomment // this.detector.detectChanges() method.

And detectChanges is imported from below library of angular:

private detector: ChangeDetectorRef,

Can anyone help me please to overcome this bug? It's really annoying and my code now has a lot of detectChanges everywhere right after any code that needs two-way data binding!

thanks in advance

Update

my .html file

 <table class="table table-bordered table-striped table-responsive"
                           style="display: inline-table;">
                        <thead>
                        <tr style="left: 0;">
                            <th><span>test</span></th>
                        </tr>
                        </thead>
                        <tbody>
                            <tr style="left: 0;" *ngFor="let d of myData">
                               <td>{{d.test}}</td>
                            </tr>
                        </tbody>
                    </table>
8
  • Why not set this.myService.getData() directly to this.myData, making it an Observable, and use async pipe on it (e.g. myData | async) in the template? Commented Jan 18, 2020 at 16:37
  • can you explain with more details and maybe in answer section. I really appreciate any help ;) Commented Jan 18, 2020 at 16:39
  • Can you show us your template (.html) first? Commented Jan 18, 2020 at 16:41
  • it's normal html. I update a section of it. Commented Jan 18, 2020 at 16:46
  • 1
    check there is a changeDetection: ChangeDetectionStrategy.OnPush in your @Component decorator config. Delete it, if you want angular CD to dirty checking for you after something async event happened. Commented Jan 18, 2020 at 18:01

1 Answer 1

2

Unlike the comments I don't like to do the async in the HTML, I do it the same way you have coded above. My questions are what is your ChangeDetectionStrategyset to on the component. Some of them will not auto notice changes and update the UI (which could explain your issue).

This is because, in app.component.ts of the template, it's using changeDetectionStrategy.onPush so basically whenever anything in angular context happens, I should use commands like detector.detectChanges(). Simply by using changeDetectionStrategy.Default everything will be normal and angular two-way binding will work fine.

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

4 Comments

Yap, I think he set the Strategy to OnPush.
I was using metronic opensource template. seems like it was on ChangeDetectionStrategy.onPush. Now that i changed it to Default everything seems to work fine. I guess just by changing that all my problems are solved. Am i Right?
When you use OnPush detect changes is triggered by either input changes, events fired , using | async in the template or manually calling detect changes or markForCheck, with OnPush you will get the best performance, but you have to get use to have in mind those 4 things when you code
thanks. problems solved appreciate. I also updated your answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.