1
votes

I made a small MEAN stack based application, and used a method of a service inside the Component life cycle. I used DoCheck life cycle to fetch new value from server whenever a change in the value is made. I though the Life cycle will be Executed whenever the value is changed, or in fixed intervals. But the DoCheck Life cycle hook is getting executed infinitely and sending infinite requests to the server.

The Component screenshot is as follows:

export class CommentsComponent implements DoCheck {

    comments: Comment[] = [];

    ngDoCheck() {
        this.commentService.getComments().subscribe((result) => {
            this.comments = result.comments;
        }, (error) => console.log(error));
    }

}

What i expected is the life cycle hook will send request to the server to fetch new comments (that other users may have posted) whenever they actually post or in fixed intervals, but the life cycle hook is sending request infinitely. (Sorry that screenshot from Chrome Developer tools, my PC freezes as soon i load the application).

The Service Code is as follows:

export class CommentService {
  getComments () {
    return this.http.get('http://www.localhost:3000/getcomment').map(res => res.json());
  }
}

PS: my application runs on port 4200, while my backend runs on port 3000 The Complete Application repository is here.

If i use OnInit lifecycle hook, then the request is made once the component is made, though it is not what i want, but it shows that the service/use of service is not wrong (incorrectly coded), the Life Cycle hook is sending the requests.

1
ngDoCheck get called on each change detection run, you shouldn't be using ngDoCheck unless you have special case. Read docs here. Why you don't you call your service from ngOnInit that will call on specified interval(using RxJS perhaps) - Pankaj Parkar
I need to call it in regular intervals, or whenever change in happens. using Observables won't help here. - Himanshu Mittal

1 Answers

1
votes

According to a documentaion, ngDoCheck

Called immediately after ngOnChanges() on every change detection run, and immediately after ngOnInit() on the first run

Note, that angular also uses NgZone to identify if html will be updated or not

From documentation

To understand how change detection works, first consider when the application needs to update the HTML. Typically, updates occur for one of the following reasons:

  • Component initialization. For example, when bootstrapping an Angular application, Angular loads the bootstrap component and triggers the ApplicationRef.tick() to call change detection and View Rendering.

  • Event listener. The DOM event listener can update the data in an Angular component and also trigger change detection, as in the following example.

  • HTTP Data Request. You can also get data from a server through an HTTP request.

  • MacroTasks, such as setTimeout() or setInterval(). You can also update the data in the callback function of a macroTask such as setTimeout().

  • MicroTasks, such as Promise.then(). Other asynchronous APIs return a Promise object (such as fetch), so the then() callback function can also update the data.

  • Other async operations. In addition to addEventListener(), setTimeout() and Promise.then(), there are other operations that can update the data asynchronously. Some examples include WebSocket.onmessage() and Canvas.toBlob().

After this events Angular runs change detection again to detects that data could have changed.

So in your code you are making Http request, after that Angular runs detection again to check if data was changed or not and called ngDoCheck again. And in ngDoCheck you are making http request again. That why you are getting infinity loop.

Now to get commnet from your server you can create rxjs interval

import { interval } from 'rxjs';
----
export class Appcomponent {
  ngOninit() {
    interval(3000).subscribe(x => {
      this.commentService.getComments().subscribe((result) => {
        this.comments = result.comments;
      }, (error) => console.log(error));
    })
  }

}