Reputation: 437
Getting issues with the view not recognizing value changes on a component
I've tried using ChangeDetectorRef
and still not getting any results. tried a bunch of thing and iv'e spent way to much time on something that i think should just work. I have a feeling its something to do with the way the gapi
is handeling the onsucess
function but I've also tried binding it down, wrapping it in other functions, nothing seems to work.
The onsuccess
runs almost immediately but alas even if i log out and log back in i get the same results.
Am I missing something here?
header.component.html<mat-toolbar color="">
<span routerLink="">Hub</span>
<span class="spacer"></span>
<ul >
<li [hidden]="!userIsAuthenticated" >
<a mat-button (click)="onLogout()" routerLinkActive="mat-accent">LogOut</a>
</li>
<li [hidden]="userIsAuthenticated">
<app-google-signin></app-google-signin>
</li>
</ul>
</mat-toolbar>
header.component.ts
import {AfterViewInit, ChangeDetectorRef, Component, OnDestroy, OnInit} from '@angular/core';
import {AuthService} from '../auth/auth.service';
import {Subscription} from 'rxjs';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit, OnDestroy {
private userIsAuthenticated = false;
private loggingIn = false;
private authStatusListenerSub: Subscription;
private loggingInSub: Subscription;
constructor(private authService: AuthService, private ref: ChangeDetectorRef) {
}
ngOnInit() {
this.userIsAuthenticated = this.authService.getIsAuthenticated();
this.loggingInSub = this.authService.getLoggingInListener().subscribe(loggingIn => {
this.loggingIn = loggingIn
console.log(`Logging In: ${loggingIn}`)
this.ref.markForCheck()
})
this.authStatusListenerSub = this.authService.getAuthStatusListener().subscribe(isAuthenticated=>{
this.userIsAuthenticated = isAuthenticated
console.log(`Authenticated: ${isAuthenticated}`)
});
}
ngOnDestroy() {
this.authStatusListenerSub.unsubscribe();
}
}
auth.service.ts
import {EventEmitter, Injectable, Output} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Subject} from 'rxjs';
declare const gapi: any;
@Injectable({
providedIn: 'root'
})
export class AuthService {
public CLIENT_ID = '[clientId]';
private isAuthenticated = false;
private loggingIn = false;
@Output() authStatus = new EventEmitter<boolean>()
private authStatusListener = new Subject<boolean>();
private loggingInListener = new Subject<boolean>();
constructor(private http: HttpClient) {
}
onGoogleSignIn(googleUser) {
this.loggingIn = true;
this.loggingInListener.next(true)
const googleToken = googleUser.getAuthResponse().id_token;
this.http.post<{ message: string, access: boolean }>(
'[login url]',
{loginToken: googleToken},
{withCredentials: true})
.subscribe(
res => {
console.log(res.message);
this.loggingIn = false;
this.loggingInListener.next(false)
this.isAuthenticated = true;
this.authStatusListener.next(true);
},
(err) => {
this.loggingIn = false;
this.loggingInListener.next(false)
this.logout();
});
}
getIsAuthenticated() {
return this.isAuthenticated;
}
getAuthStatusListener() {
return this.authStatusListener.asObservable();
}
getLoggingInListener() {
return this.loggingInListener.asObservable()
}
}
google-signin.component.ts
import {AfterViewInit, Component, ElementRef, OnInit} from '@angular/core';
import {AuthService} from '../auth.service';
declare const gapi: any;
@Component({
selector: 'app-google-signin',
templateUrl: './google-signin.component.html',
styleUrls: ['./google-signin.component.scss']
})
export class GoogleSigninComponent implements OnInit, AfterViewInit {
public auth2: any;
constructor(
private element: ElementRef,
private authService: AuthService,
) {
}
ngOnInit() {
}
ngAfterViewInit() {
this.googleInit();
}
public googleInit() {
gapi.load('auth2', () => {
this.auth2 = gapi.auth2.init({
client_id: this.authService.CLIENT_ID,
cookie_policy: 'single_host_origin',
});
const element = gapi.signin2.render('app-google-signin', {
scope: 'profile email',
longtitle: true,
theme: 'dark',
onsuccess: this.authService.onGoogleSignIn.bind(this.authService),
onfailure: err => console.log(err)
});
});
}
}
Upvotes: 4
Views: 9263
Reputation: 21367
try to trigger change detection manually and use onPush change detection strategy
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush // add this
})
export class HeaderComponent implements OnInit, OnDestroy {
private userIsAuthenticated = false;
private loggingIn = false;
private authStatusListenerSub: Subscription;
private loggingInSub: Subscription;
constructor(private authService: AuthService, private cdr: ChangeDetectorRef) {
}
ngOnInit() {
this.userIsAuthenticated = this.authService.getIsAuthenticated();
this.loggingInSub = this.authService.getLoggingInListener().subscribe(loggingIn => {
this.loggingIn = loggingIn
console.log(`Logging In: ${loggingIn}`)
this.cdr.detectChanges(); // *trigger change here*
})
this.authStatusListenerSub = this.authService.getAuthStatusListener().subscribe(isAuthenticated=>{
this.userIsAuthenticated = isAuthenticated
console.log(`Authenticated: ${isAuthenticated}`)
});
}
ngOnDestroy() {
this.authStatusListenerSub.unsubscribe();
}
}
Upvotes: 4