Menggunakan Authentication Pada Project Buku Resep – 10

Pada modul ini kita akan mengimplementasikan logout.

Buka file auth.service.ts, lalu tambahkan

  • Inject router, akan digunakan untuk navigasi saat method logout dijalankan.
  • Method logout
import {Injectable} from '@angular/core';
import {HttpClient, HttpErrorResponse} from '@angular/common/http';
//import Router jika IDE tidak otomatis
import { Router } from '@angular/router';

import { catchError, tap } from 'rxjs/operators';
import { Subject, throwError } from 'rxjs';

import { User } from './user.model';

export interface AuthResponse {
    idToken: string;
    email: string;
    refreshToken: string;
    expiresIn: string;
    localId: string;
    registered?: boolean; 
}

@Injectable({providedIn: 'root'})
export class AuthService {
    user = new Subject<User>();
    token = "";

    //inject router
    constructor(private http: HttpClient, private router : Router){}

    signUp(email: string, pswrd: string){
        return this.http
        .post<AuthResponse>('https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=AIzaSyAHq81IV8SqS_n6KL9wEmuB_qs3_8J4szU',
            {
                email: email, 
                password: pswrd, 
                returnSecureToken: true
            }
        )
        .pipe(catchError(this.errHandling), tap(respData=>{
            this.handleAuth(respData.email, respData.localId, respData.idToken, +respData.expiresIn);
        }));
    }

    login(email: string, pswrd: string){
        return this.http
        .post<AuthResponse>('https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=AIzaSyAHq81IV8SqS_n6KL9wEmuB_qs3_8J4szU',
            {
                email: email, 
                password: pswrd, 
                returnSecureToken: true                
            }
        ).pipe(catchError(this.errHandling), tap(respData=>{
            this.handleAuth(respData.email, respData.localId, respData.idToken, +respData.expiresIn);
        }));   
    }

    //method logout
    logout(){
        this.user.next(undefined);
        this.token = "";
        this.router.navigate(['/auth']);
    }

    private handleAuth(email: string, userId: string, token: string, expiresIn: number){
        const expDate = new Date(new Date().getTime()+ (expiresIn*1000));
        const user = new User(email, userId, token, expDate);
        this.user.next(user);
        this.token = token;
    }

    private errHandling(errResp: HttpErrorResponse){
        let errMsg = 'Unknown Error...';

        if (!errResp.error || !errResp.error.error){
            return throwError(errMsg);
        }
        switch(errResp.error.error.message){
            case 'EMAIL_EXISTS':      
                errMsg = 'Email sudah terdaftar';
                break;
            case 'EMAIL_NOT_FOUND':
                errMsg = 'User belum terdaftar';
                break;
            case 'INVALID_PASSWORD':
                errMsg = 'User atau Password salah';
                break;                
        }
        return throwError(errMsg);
    }
}

Kemudian buka file header.component.ts, tambahkan method untuk handling click listener logout.

import { Component, OnDestroy, OnInit } from "@angular/core";
import { Subscription } from "rxjs";
import { AuthService } from "../auth/auth.service";
import { DataStorageService } from "../shared/data-storage.service";

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

export class HeaderComponent implements OnInit, OnDestroy{
    isAuthenticated = false;
    private userSub! : Subscription;

    constructor(private dataStorageSrv : DataStorageService, private authSrv : AuthService){}

    ngOnInit(): void {
        this.userSub =  this.authSrv.user.subscribe(user=>{
            this.isAuthenticated = !user ? false : true;
            //this.isAuthenticated = !!user;
        });
    }

    ngOnDestroy(): void {
        this.userSub.unsubscribe;
    }

    onSaveData(){
        this.dataStorageSrv.storeRecipes();
    }

    onFetchData(){
        this.dataStorageSrv.fetchRecipes().subscribe();
    }

    //method handling logout listener
    onLogout(){
        this.authSrv.logout();
    }
}

Buka file header.component.html, Kemudian tambahkan code click listener pada menu logout.

<nav class="navbar navbar-expand-lg navbar-light bg-light">
    <div class="container-fluid">
      <a class="navbar-brand" href="#">Buku Resep</a>
      <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav me-auto mb-2 mb-lg-0">     
          <li class="nav-item" *ngIf="isAuthenticated"><a class="nav-link" routerLinkActive="active" routerLink="/recipes">Recipes</a></li>
          <li class="nav-item" *ngIf="!isAuthenticated"><a class="nav-link" routerLinkActive="active" routerLink="/auth" >Login</a></li>
          <li class="nav-item"><a class="nav-link" routerLinkActive="active" routerLink="/shopping-list" >Shopping List</a></li>         
        </ul>
        <ul class="nav navbar-nav navbar-right">
          <!-- tambahkan click listener logout -->
          <li class="nav-item" *ngIf="isAuthenticated">
            <a class="nav-link" style="cursor: pointer;" (click)="onLogout()">Logout</a>
          </li>
          <li class="dropdown" appDropDown *ngIf="isAuthenticated">
            <a class="nav-link dropdown-toggle" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false"
            appDropdown>
              Manage
            </a>
            <ul class="dropdown-menu" aria-labelledby="navbarDropdown">
              <li><a class="dropdown-item" (click)="onSaveData()">Save Data</a></li>
              <li><a class="dropdown-item" (click)="onFetchData()">Get Data</a></li>
            </ul>
          </li>
        </ul>
      </div>
    </div>
  </nav>

Jika Anda jalankan, sesuai ekspektasi, logout sudah berhasil kita implementasikan.

Sharing is caring:

Leave a Comment