I have a service:
@Injectable({ providedIn: 'root' })
export class AuthenticationService {
signInChange: Subject<boolean> = new Subject<boolean>();
isSignedIn: boolean;
constructor() {
this.isSignedIn = false;
}
signInChange: Subject<boolean> = new Subject<boolean>();
isSignedIn: boolean;
login() {
this.auth2.signIn()
.then(user => {
this.isSignedIn = true;
this.signInChange.next(this.isSignedIn)
})
.catch(error => {
console.log("Error signing in")
})
}
logout() {
this.auth2.signOut()
.then(user => {
this.isSignedIn = false;
this.signInChange.next(this.isSignedIn)
})
.catch(error => {
console.log("Error signing out")
})
}
and a ponent:
export class HomeComponent implements OnInit {
signInSubscription: Subscription;
isSignedIn: any;
constructor(private authService: AuthenticationService) {
this.isSignedIn = authService.isSignedIn;
this.signInSubscription = authService.signInChange.subscribe(value => {
console.log("status changed to: " + value)
this.isSignedIn = value
})
}
checkValues() {
console.log("Component says: " + this.isSignedIn);
console.log("Auth says: " + this.authService.isSignedIn)
}
and here is the HTML:
<div id = "login-test">
<div class="g-signin2"></div>
<button (click)="signIn()">Sign in</button>
<button (click)="signOut()">Sign out</button>
<button (click)="checkValues()">Check values</button>
<p>{{this.isSignedIn}}</p>
</div>
So the observable works as expected (eg. when the sign in status is change the correct status is logged) BUT on the template itself the variable does not update when a change is observed.
Here's what I dont understand:
When I click the Check Values button, the output is ALWAYS correct. The isSignedIn property is being set correctly every time there is an update in the service. BUT THE TEMPLATE ITSELF DOESN'T UPDATE.
If I set up a button to only toggle the value {{this.isSignedIn}}, the template updates real time. Why will it not update real time if the change is ing from the observable?!?
I have a service:
@Injectable({ providedIn: 'root' })
export class AuthenticationService {
signInChange: Subject<boolean> = new Subject<boolean>();
isSignedIn: boolean;
constructor() {
this.isSignedIn = false;
}
signInChange: Subject<boolean> = new Subject<boolean>();
isSignedIn: boolean;
login() {
this.auth2.signIn()
.then(user => {
this.isSignedIn = true;
this.signInChange.next(this.isSignedIn)
})
.catch(error => {
console.log("Error signing in")
})
}
logout() {
this.auth2.signOut()
.then(user => {
this.isSignedIn = false;
this.signInChange.next(this.isSignedIn)
})
.catch(error => {
console.log("Error signing out")
})
}
and a ponent:
export class HomeComponent implements OnInit {
signInSubscription: Subscription;
isSignedIn: any;
constructor(private authService: AuthenticationService) {
this.isSignedIn = authService.isSignedIn;
this.signInSubscription = authService.signInChange.subscribe(value => {
console.log("status changed to: " + value)
this.isSignedIn = value
})
}
checkValues() {
console.log("Component says: " + this.isSignedIn);
console.log("Auth says: " + this.authService.isSignedIn)
}
and here is the HTML:
<div id = "login-test">
<div class="g-signin2"></div>
<button (click)="signIn()">Sign in</button>
<button (click)="signOut()">Sign out</button>
<button (click)="checkValues()">Check values</button>
<p>{{this.isSignedIn}}</p>
</div>
So the observable works as expected (eg. when the sign in status is change the correct status is logged) BUT on the template itself the variable does not update when a change is observed.
Here's what I dont understand:
When I click the Check Values button, the output is ALWAYS correct. The isSignedIn property is being set correctly every time there is an update in the service. BUT THE TEMPLATE ITSELF DOESN'T UPDATE.
If I set up a button to only toggle the value {{this.isSignedIn}}, the template updates real time. Why will it not update real time if the change is ing from the observable?!?
1 Answer
Reset to default 5Because the variable isSignedIn
in HomeComponent
is assigned once in it's constructor and never re-assigned. And you are on the right path setting up an observable in the service. When you need the up-to-date value in ponent, use only the observable and do not use the boolean flag from the service directly.
Do the following in the ponent. Move the assignment inside the subscription and avoid using the boolean flag from the service directly.
import { Component, ngOnInit, ChangeDetectorRef } from '@angular/core';
export class HomeComponent implements OnInit {
signInSubscription: Subscription;
isSignedIn: any;
constructor(private authService: AuthenticationService, private changeDetectorRef: ChangeDetectorRef) {
this.isSignedIn = authService.isSignedIn;
this.signInSubscription = authService.signInChange.subscribe(value => {
console.log("status changed to: " + value)
this.isSignedIn = value;
this.changeDetectorRef.detectChanges();
})
}
checkValues() {
console.log("Component says: " + this.isSignedIn);
console.log("Auth says: " + this.authService.isSignedIn)
}
}
Edit - include ChangeDetectorRef