nick.cook
nick.cook

Reputation: 2141

Angular / Firebase Authentication - Make boolean Observable from service to component?

I'm trying to change the [hidden] properties of some elements in my app.component.html file based on the 'isAuthenticated' boolean value present in the component controller, which is matched to the property of the same name defined in my auth.service service.

So when there is an authenticated user, and the boolean value for 'isAuthenticated' is true, the elements should show.

Currently, the boolean is set to false by default and updated where in the same auth.service file where it is defined upon successful login, but I need the value to update in the app.component.ts file as well, but can't do this due to 'Observable' not being assignable to booleans.

auth.service.ts

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import * as firebase from 'firebase/app';
import { AngularFireAuth } from 'angularfire2/auth';

@Injectable()

export class AuthService {

private user: Observable<firebase.User>;

isAuthenticated: boolean = false;

  constructor(private firebaseAuth: AngularFireAuth, private router: Router) {
      this.user = firebaseAuth.authState;
  }

signIn(email: string, password: string) {
    this.firebaseAuth
        .auth
        .signInWithEmailAndPassword(email, password)
        .then(value => {
            console.log('Signed In');
            this.isAuthenticated = true;
            this.router.navigateByUrl('/dashboard');
        })
        .catch(err => {
            console.log('Sign-In Error: ', err.message);
        });
}

signOut() {
    this.firebaseAuth
        .auth
        .signOut();
    this.isAuthenticated = false;
    this.router.navigateByUrl('/login');
    console.log('Signed Out');
}

register(email: string, password: string) {
    this.firebaseAuth
        .auth
        .createUserWithEmailAndPassword(email, password)
        .then(value => {
            console.log('Registration Successful', value);
         })
         .catch(err => {
            console.log('Registration Error: ', err.message);
        });    
}

}

can-activate-route.guard.ts

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';

import { AuthService } from './services/auth.service';

@Injectable()

export class CanActivateRouteGuard implements CanActivate {

constructor(private auth: AuthService) { }

canActivate (
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    return this.auth.isAuthenticated;
}

}

app.component.ts

import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';

import { AngularFirestore } from 'angularfire2/firestore';

import { UsersService } from './services/users.service';
import { AuthService } from './services/auth.service';

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

export class AppComponent {

isAuthenticated: boolean;
titles: any[];

constructor(public db: AngularFirestore, private usersService: UsersService, public authService: AuthService, private router: Router) {
    this.isAuthenticated = this.authService.isAuthenticated;
}

app.component.html

<button mat-button (click)="signOut()" [hidden]="isAuthenticated">Sign Out</button>

Upvotes: 3

Views: 1273

Answers (1)

DeborahK
DeborahK

Reputation: 60518

Try changing your component (app.component.ts) from this:

isAuthenticated: boolean;

To this:

export class AppComponent {

   get isAuthenticated(): boolean {
       return this.authService.isAuthenticated;
   }

   titles: any[];

   constructor(public db: AngularFirestore, 
               private usersService: UsersService, 
               public authService: AuthService, 
               private router: Router) { }
}

That will ensure that as the service value changes, the component property will always get the most recent value.

Upvotes: 1

Related Questions