How to force a component's re-rendering in Angular 2? For debug purposes working with Redux i'd like to force a component to re-render it's view, is that possible?
-
What do you mean by "re-rendering". Update the bindings? – Günter Zöchbauer Jan 30 '16 at 18:23
-
Just a quick question why you need to force re-rendering? – Tuong Le Oct 18 '16 at 03:16
-
5Possible duplicate of [Triggering Angular2 change detection manually](http://stackoverflow.com/questions/34827334/triggering-angular2-change-detection-manually) – blo0p3r Nov 09 '16 at 15:46
6 Answers
Rendering happens after change detection. To force change detection, so that component property values that have changed get propagated to the DOM (and then the browser will render those changes in the view), here are some options:
- ApplicationRef.tick() - similar to Angular 1's
$rootScope.$digest()
-- i.e., check the full component tree - NgZone.run(callback) - similar to
$rootScope.$apply(callback)
-- i.e., evaluate the callback function inside the Angular 2 zone. I think, but I'm not sure, that this ends up checking the full component tree after executing the callback function. - ChangeDetectorRef.detectChanges() - similar to
$scope.$digest()
-- i.e., check only this component and its children
You will need to import and then inject ApplicationRef
, NgZone
, or ChangeDetectorRef
into your component.
For your particular scenario, I would recommend the last option if only a single component has changed.

- 362,217
- 114
- 495
- 492
-
2Any working code on ChangeDetectorRef for final version of angular2? I am now facing a situation where view is not updated after a http's post request to create a new user and then on success pushing the new object to the existing old userlist (used to iterate in view). Quite strange that `this is the first time I am facing an update not working in ng2`. The change detection strategy is default so i know i have not messed up with the change detection strategy. – Gary Oct 11 '16 at 16:33
-
1@Gary, you should post a new question and include your component and your service code (ideally, include a minimal plunker demonstrating the issue). A common problem I've seen is not using the proper `this` context in the POST callback. – Mark Rajcok Oct 11 '16 at 16:55
-
Do you know if I can manually trigger the pipes whenever I perform a change? I've tried to trigger the change detection but the pipe doesn't update... I've also tried with `pure:false` in the pipe. It works but it is way too expensive (inefficient) for my use case. – Nate May 03 '17 at 15:02
-
1@ncohen, I'm not aware of any way to manually trigger a pipe update. You could use a pure pipe and change the object reference whenever you want to trigger an update. This is discussed under the "Pure Pipes" section of the [Pipes doc](https://angular.io/docs/ts/latest/guide/pipes.html). Depending on your use case, you might want to use a component property instead of a pipe. This technique is briefly discussed at the end of the Pipes doc. – Mark Rajcok May 10 '17 at 03:27
-
1
-
1ChangeDetectorRef.detectChanges() does not work for me. I think, it's because there are no changes. I just want to tigger redrawing / computing. Update pipe values. I want to trigger it every x seconds by setInterval. I thinks re-assigning the variable is currently a easy way to do this. But maybe not the best. – Domske May 20 '19 at 16:54
tx, found the workaround I needed:
constructor(private zone:NgZone) {
// enable to for time travel
this.appStore.subscribe((state) => {
this.zone.run(() => {
console.log('enabled time travel');
});
});
running zone.run will force the component to re-render

- 24,129
- 22
- 65
- 104
-
8what is appStore in this context - which kind of variable and its type ? seems to be observable ... but my observable is inside the component which I want to refresh on a click of a button ... and I do not know how to access a child component method/variable from parent/current location – Abdeali Chandanwala Aug 24 '16 at 04:15
ChangeDetectorRef approach
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
export class MyComponent {
constructor(private cdr: ChangeDetectorRef) { }
selected(item: any) {
if (item == 'Department')
this.isDepartment = true;
else
this.isDepartment = false;
this.cdr.detectChanges();
}
}

- 3,442
- 3
- 25
- 40

- 1,698
- 1
- 17
- 20
I force reload my component using *ngIf.
All the components inside my container goes back to the full lifecycle hooks .
In the template :
<ng-container *ngIf="_reload">
components here
</ng-container>
Then in the ts file :
public _reload = true;
private reload() {
setTimeout(() => this._reload = false);
setTimeout(() => this._reload = true);
}

- 1,317
- 16
- 19
-
Thanks for this, @loonis! I felt like this should work, and I had everything except for the `setTimeout()`. Now mine is working with a simple and lightweight solution! – LHM Nov 14 '19 at 04:29
-
1 thing to note - the container disappearing and appearing again can can cause size changes and the page could flicker – Eggcellentos Jul 02 '20 at 13:29
-
1This is the best solution for me. This solved my translation issue using my custom translator pipe. – supernerd Jan 01 '22 at 08:46
-
Thanks, a little bit hacky, but that is the only solution that works for my case (slider of videos) – Pierre Jun 12 '22 at 03:00
-
Except that if you are using @ViewChild() on this component, to get it, then it will be undefined. – herve Dec 22 '22 at 15:00
Other answers here provide solutions for triggering change detection cycles that will update component's view (which is not same as full re-render).
Full re-render, which would destroy and reinitialize component (calling all lifecycle hooks and rebuilding view) can be done by using ng-template
, ng-container
and ViewContainerRef
in following way:
<div>
<ng-container #outlet >
</ng-container>
</div>
<ng-template #content>
<child></child>
</ng-template>
Then in component having reference to both #outlet
and #content
we can clear outlets' content and insert another instance of child component:
@ViewChild("outlet", {read: ViewContainerRef}) outletRef: ViewContainerRef;
@ViewChild("content", {read: TemplateRef}) contentRef: TemplateRef<any>;
private rerender() {
this.outletRef.clear();
this.outletRef.createEmbeddedView(this.contentRef);
}
Additionally initial content should be inserted on AfterContentInit
hook:
ngAfterContentInit() {
this.outletRef.createEmbeddedView(this.contentRef);
}
Full working solution can be found here https://stackblitz.com/edit/angular-component-rerender .

- 1,091
- 9
- 14
-
1I guess that in previous versions of angular this hook may be correct (not sure). But with newer one (v13 for me) it does not work and anybody interested in this solution should use `ngAfterViewInit`. BTW, it interestingly is the only solution that worked for me when input's held the previous values despite form model was correct. This occurred when I was switching between routes differentiated by the `:id` route. In the end I had to call the `rerender` function every time that navigation ended. – Marcin Wojtach Jul 07 '22 at 13:48
ChangeDetectorRef.detectChanges()
is usually the most focused way of doing this. ApplicationRef.tick()
is usually too much of a sledgehammer approach.
To use ChangeDetectorRef.detectChanges()
, you'll need this at the top of your component:
import { ChangeDetectorRef } from '@angular/core';
... then, usually you alias that when you inject it in your constructor like this:
constructor( private cdr: ChangeDetectorRef ) { ... }
Then, in the appropriate place, you call it like this:
this.cdr.detectChanges();
Where you call ChangeDetectorRef.detectChanges()
can be highly significant. You need to completely understand the life cycle and exactly how your application is functioning and rendering its components. There's no substitute here for completely doing your homework and making sure you understand the Angular lifecycle inside out. Then, once you understand that, you can use ChangeDetectorRef.detectChanges()
appropriately (sometimes it's very easy to understand where you should use it, other times it can be very complex).

- 28,994
- 18
- 176
- 206