import { Injectable } from '@angular/core' ; import { HttpClient } from '@angular/common/http' ; import { Observable , BehaviorSubject , ReplaySubject } from 'rxjs' ; import { ApiService } from './api.service' ; import { JwtService } from './jwt.service' ; import { User } from '../models' ; import { map , distinctUntilChanged } from 'rxjs/operators' ; @ Injectable ( ) export class UserService { private currentUserSubject = new BehaviorSubject < User > ( { } as User ) ; public currentUser = this . currentUserSubject . asObservable ( ) . pipe ( distinctUntilChanged ( ) ) ; private isAuthenticatedSubject = new ReplaySubject < boolean > ( 1 ) ; public isAuthenticated = this . isAuthenticatedSubject . asObservable ( ) ; constructor ( private apiService , private http , private jwtService ) { } populate ( ) { if ( this . jwtService . getToken ( ) ) { this . apiService . get ( '/user' ) . subscribe ( data => this . setAuth ( data . user ) , err => this . purgeAuth ( ) ) ; } else { this . purgeAuth ( ) ; } } setAuth ( user ) { this . jwtService . saveToken ( user . token ) ; this . currentUserSubject . next ( user ) ; this . isAuthenticatedSubject . next ( true ) ; } purgeAuth ( ) { this . jwtService . destroyToken ( ) ; this . currentUserSubject . next ( { } as User ) ; this . isAuthenticatedSubject . next ( false ) ; } attemptAuth ( type , credentials ) { const route = ( type === 'login' ) ? '/login' : '' ; return this . apiService . post ( '/users' + route , { user : credentials } ) . pipe ( map ( data => { this . setAuth ( data . user ) ; return data ; } ) ) ; } getCurrentUser ( ) { return this . currentUserSubject . value ; } update ( user ) { return this . apiService . put ( '/user' , { user } ) . pipe ( map ( data => { this . currentUserSubject . next ( data . user ) ; return data . user ; } ) ) ; } }