Having trouble with the view not detecting changes in value on a component. I've attempted to use ChangeDetectorRef
without success. After trying various solutions and spending an excessive amount of time on something that should work smoothly, it seems like there might be an issue with how the gapi
is handling the onsuccess
function. I've tried binding it down and wrapping it in different functions, but nothing seems to resolve the problem.
The onsuccess
function executes almost immediately, but even after logging out and back in, the same results persist.
Do you think there's something crucial that I'm overlooking 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)
});
});
}
}