0

First I set the isLoading property to "true" so the element isn't loaded yet.(this happens on AppComponent)

  export class AppComponent implements OnInit {
  isLoading = true;
  constructor(private authService: AuthService) {}
 .
 .
 .

bellow in the ngOnInit hook I have:

firebase.auth().onAuthStateChanged((user) => {
      if (user) {
        // User is signed in.
        this.authService.user = new User(user.displayName, user.email, user.photoURL, user.uid);

        console.log(user);
        this.isLoading = false;
        this.authService.isLogIn.next(true);
      } else {
        // No user is signed in.
        console.error('no user is login');
        this.authService.isLogIn.next(false);
      }
    });
    .
    .
    .

this code is an asynchronous one and I want that the user wait to check if him is login or not so I can change the header's UI. Besides I have another component that wraps the header. I call it inside the AppComponent with *ngIf=isLoading

<div>
  <app-header *ngIf="!isLoading"></app-header>
</div>


<div>
  <router-outlet></router-outlet>
</div>

The problem is that when the isLoading change its value to false I've never seen the AppHeader been rendered. So, why *ngIf doesn't evaluate that property again?

Here my AuthService:

import * as firebase from 'firebase';
// import {User} from "../../auth/models/user.model";
import {Router} from '@angular/router';
import { Injectable } from "@angular/core";
import {Subject} from "rxjs/Subject";
import {User} from "../../auth/models/user.model";

@Injectable()
export class AuthService {
  token: string;
  isLogIn = new Subject<boolean>();
  user: User;
  constructor(private router: Router){}

  signinWithFacebook() {
    const provider = new firebase.auth.FacebookAuthProvider();
    provider.addScope('user_location');
    return firebase.auth().signInWithPopup(provider)
      .then(
        (res) => {
          console.log(res);
          this.getTokenId();
          localStorage.setItem('userInfo', JSON.stringify(firebase.auth().currentUser.providerData[0]));
          const userInfo = firebase.auth().currentUser.providerData[0];
          this.user = new User(userInfo.displayName, userInfo.email, userInfo.photoURL, userInfo.uid);

          this.isLogIn.next(true);
          this.router.navigate(['/dashboard']);
        }
      );
  }

  getTokenId() {
    firebase.auth().currentUser.getIdToken()
      .then(
        (tk) => {
          return this.token = tk;
        }
      );
  }

  logout() {
    return firebase.auth().signOut();
    // handle in component
  }

  getLocalUserInfo(): boolean {
    if(localStorage.getItem('userInfo')) {
      const transformStoredUser = JSON.parse(localStorage.getItem('userInfo'));
      this.user = new User(transformStoredUser.displayName, transformStoredUser.email, transformStoredUser.photoURL, transformStoredUser.uid);
      return true;
    } else {
      return false;
    }
  }
  isLogin():boolean {
    if (localStorage.getItem('userInfo')) {
      return true;
    }
    return false;
  }
}

AppHeader.ts

import { Component, OnInit } from '@angular/core';
import {AuthService} from '../../public/services/auth.service';
import * as  firebase from 'firebase';
import {User} from "../../auth/models/user.model";
import {Observable} from "rxjs/Observable";

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
  isActivated = false;
  constructor(private authService: AuthService) { }
  ngOnInit() {
    this.authService.isLogIn.asObservable().subscribe(
      (data: boolean) => {
        this.isActivated = data;
      }
    );
    this.isActivated = this.authService.isLogin();
  }

}

AppHeader template

<nav class="navbar navbar-expand-lg navbar-dark bg-custom-nav px-5">
  <a class="navbar-brand" routerLink="/">MovieApp</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="container-fluid">
    <div class="collapse navbar-collapse d-lg-flex justify-content-lg-between row" id="navbarNavAltMarkup">
      <div class="navbar-nav px-sm-4 px-lg-0">
        <a class="nav-item nav-link text-white"
           routerLink="/"
           routerLinkActive="active font-weight-bold"
           [routerLinkActiveOptions]="{exact: true}">Inicio</a>
      </div>
      <div class="col-lg-8">
        <app-search-bar></app-search-bar>
      </div>
      <div class="row">
        <ng-template [ngIf]="!isActivated">
          <a class="nav-item nav-link text-white anchor-hover"

             routerLink="/login"
             routerLinkActive="active font-weight-bold">
            <i class="fa fa-sign-in pr-2" aria-hidden="true"></i>Ingresar
          </a>
        </ng-template>
        <ng-template [ngIf]="isActivated">
          <!--DROPDOWN PROFILE-->
          <div class="btn-group" role="group" *ngIf="authService.user">
            <button id="btnGroupDrop1" type="button" class="btn btn-light dropdown-toggle pointer" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
              {{authService.user.displayName}}
            </button>
            <div class="dropdown-menu dropdown-menu-right" aria-labelledby="btnGroupDrop1">
              <a class="dropdown-item" href="#">Dropdown link</a>
              <a class="dropdown-item" href="#">Dropdown link</a>
            </div>
          </div>
          <a class="nav-item nav-link text-white anchor-hover"
             routerLink="/dashboard"
             routerLinkActive="active font-weight-bold">
            <i class="fa fa-sign-in pr-2" aria-hidden="true"></i>Dashboard
          </a>
        </ng-template>

      </div>
    </div>
  </div>
</nav>
5
  • Can you show your routing configs (paths)? Commented Sep 28, 2017 at 1:07
  • sure, check this link: ibb.co/etZvr5 Commented Sep 28, 2017 at 1:17
  • Thanks. Can I also see your AuthService? Commented Sep 28, 2017 at 1:27
  • I've added the AuthService above Commented Sep 28, 2017 at 1:32
  • Note that I'm trying new things. You can see the isLogin Subject and I'm subscribing to it on the AppHeader component. I'm goin to update the post again but remember that this is something I'm testing. Commented Sep 28, 2017 at 1:35

1 Answer 1

0

Could you try this,

modify your AuthService,

isLogIn = new BehaviorSubject(false);

// add a getter
get isLogin() {
 return this.isLogIn;
}

Then in your template,

<app-header *ngIf="authService.isLogin | async"></app-header>
Sign up to request clarification or add additional context in comments.

4 Comments

@Lucas you have to clean up the recent changes you made using observables though. I'm referring to this with respect to the initial OP you had
Hi. I've created another post with a new issue. I'm not using the approach of this post any more but thanks anyways!.
You can visit my question ask : stackoverflow.com/questions/46459949/…
Just saw your question there. I think the current answer proposed is almost going the way I suggested. I will let him continue on with it. Let me know if you were still unable to get it working after trying his method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.