0

Component:

import { Component, OnInit } from '@angular/core';
import { AngularFire, FirebaseObjectObservable } from 'angularfire2';
import { Router } from '@angular/router';

@Component({
  selector: 'app-header',
  templateUrl: './app-header.component.html',
  styleUrls: ['./app-header.component.css']
})

export class AppHeaderComponent implements OnInit {
  isLoggedIn: any;
  userEmail: any;
  email: string;
  item: FirebaseObjectObservable<any>;

  constructor(public af: AngularFire, private router: Router) {
    var auth = this.af.auth.subscribe( (user) => {
      if (user) {
        this.isLoggedIn = true;
        this.userEmail = this.af.auth.subscribe(auth => {
          this.email = auth.auth.email;
          this.item = af.database.object('/users/'+ auth.auth.uid);
          console.log(this.email);
        });
      } else {
        this.isLoggedIn = false;
      }
    });

  }

  logout() {
    this.af.auth.logout();
    this.router.navigate(['login']);
  }

  ngOnInit() {

  }

}

Everything works perfectly, but when the logout() function is called, I get the following error in console and I can't seem to manage to fix it:

TypeError: Cannot read property 'auth' of null

Nothing break as far as I can tell, but I'm fairly new to learning all of this and would like to clean my code up as much as possible. Thank you.

Edit: Added HTML

<nav class="navbar navbar-inverse bg-inverse navbar-toggleable-md">
  <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#containerNavbar" aria-controls="containerNavbar" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item"
          [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}">
        <a class="nav-link" routerLink="/">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item"
          [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}">
        <a class="nav-link" routerLink="/about">About</a>
      </li>
    </ul>
    <div class="">
      <ul class="navbar-nav mr-auto">
        <li class="nav-item"
            [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}">
          <a class="nav-link" routerLink="/login" *ngIf="!isLoggedIn">Login</a>
        </li>
        <li class="nav-item"
            [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}">
          <a class="nav-link" routerLink="/register" *ngIf="!isLoggedIn">Register</a>
        </li>
        <li class="nav-item dropdown" *ngIf="isLoggedIn">
          <a class="nav-link dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            {{ (item | async)?.battleTag }}
          </a>
          <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
            <a class="dropdown-item" routerLink="/profile">Profile</a>
            <a class="dropdown-item">Settings</a>
            <a class="dropdown-item" (click)="logoutModal.show()">Logout</a>
          </div>
        </li>
      </ul>
    </div>
  </div>
</nav>

<div class="modal fade" bsModal #logoutModal="bs-modal" [config]="{backdrop: 'static'}"
     tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Logout</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close" (click)="logoutModal.hide()">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <p>Are you sure you want to logout?</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-primary" (click)="logout();logoutModal.hide()">Logout</button>
        <button type="button" class="btn btn-secondary" (click)="logoutModal.hide()">Cancel</button>
      </div>
    </div>
  </div>
</div>
6
  • Check this answer stackoverflow.com/questions/41365528/… Commented Apr 6, 2017 at 17:34
  • I did but don't think it's really related. Commented Apr 6, 2017 at 17:41
  • Where do you call logout? Commented Apr 6, 2017 at 18:26
  • @echonax in the template of the component I posted. Commented Apr 6, 2017 at 18:57
  • What does console.log(this); log? Does it refer to the component? Can you add the html? Commented Apr 6, 2017 at 18:59

1 Answer 1

1

You need to unsubscribe from firebase auth to avoid this error.

import { Subscription } from 'rx/js';

export class AppHeaderComponent implements OnInit {

authSubscription: Subscription;

  onInit() {
     this.authSubscription = this.af.auth.subscribe( (user) => {
     ....
  }

  logout() {
    this.af.auth.logout();
    this.router.navigate(['login']);
    this.authSubscription.unsubscribe();
  }
}

P.S. It is a good habbit to unsubscribe from all subscriptions in OnDestroy() lifecycle hook.

Sign up to request clarification or add additional context in comments.

1 Comment

I've just noticed that you have subscribed on auth twice. Create two different subscriptions and unsubscribe on both of them in logout().

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.