cronicryo
cronicryo

Reputation: 437

Angular dom not updating on changes

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

Answers (1)

Fateh Mohamed
Fateh Mohamed

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

Related Questions