I have come across a puzzling scenario regarding a basic issue. The situation involves a simple component with a boolean property that is displayed in the template of the component. When I update this property within a callback function, the property is updated internally within the component, but the modified value is not reflected in the rendering. As a result, the change detection does not occur automatically, and I find myself having to trigger it manually by calling
changeDetectorRef.detectChanges();
in order to display the updated value.
This is how the template looks:
<div *ngIf="isUserLoggedIn">
<router-outlet></router-outlet>
</div>
<div *ngIf="!isUserLoggedIn">
<div id="googleBtn" (click)="onSignIn()">Sign In</div>
</div>
And here's the relevant code from the component:
gapi.load('auth2', () => {
this.auth2 = gapi.auth2.init({
client_id: '769107420471-782b0i2f3dt9u05dhrb4j21g7ajglrg6.apps.googleusercontent.com',
cookiepolicy: 'single_host_origin',
scope: 'profile email'
});
var googleBtn = document.getElementById('googleBtn');
if(googleBtn) {
this.attachSignin(document.getElementById('googleBtn'));
}
});
}
public attachSignin(element) {
this.auth2.attachClickHandler(element, {},
(googleUser) => {
this.signUpService.googleLogin(googleUser.getAuthResponse().id_token,
this.successCallback.bind(this),
this.signOut.bind(this));
}, (error) => {
alert(JSON.stringify(error, undefined, 2));
});
}
successCallback = function (data) {
// this.changeDetectorRef.detectChanges();
this.isUserLoggedIn = this.utils.isUserLoggedIn();
}
The expected behavior is as follows: initially, "isUserLoggedIn" is set to false. When the user clicks on the "Sign In" button, a function from another service is called which toggles the value of "isUserLoggedIn" in the successCallback of that function. This should also lead to the corresponding toggling of elements in the template.
However, I find it perplexing that I need to manually invoke
changeDetectorRef.detectChanges()
in order to see the changes in the DOM. I wonder why the change detection mechanism fails to work seamlessly in this callback scenario. Interestingly, when I tested it differently using a simple example like Observable.interval(2000).subscribe(x => {this.isUserLoggedIn = !this.isUserLoggedIn});
, the change detection worked perfectly fine without any manual intervention.