官术网_书友最值得收藏!

Create AuthService to help handle the authenticated state of our app

One important consideration for our AuthService is to understand that certain components in our app may benefit from getting notified when the authenticated state changes. This is a perfect use case to utilize RxJS. RxJS is a very powerful library that is used to simplify dealing with changing data and events using observables. An observable is a data type that you can use not only to listen to events, but filter, map, reduce, and run sequences of code against anytime something occurs. By using observables, we can simplify our asynchronous development dramatically. We will use a specific type of observable called the BehaviorSubject to emit changes that our components could subscribe to.

Create app/modules/core/services/auth.service.ts and add the following:

// angular
import { Injectable } from '@angular/core';

// lib
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

// app
import { DatabaseService } from './database.service';
import { LogService } from './log.service';

@Injectable()
export class AuthService {

// access our current user from anywhere
public static CURRENT_USER: any;

// subscribe to authenticated state changes
public authenticated$: BehaviorSubject<boolean> =
new BehaviorSubject(false);

constructor(
private databaseService: DatabaseService,
private logService: LogService
) {
this._init();
}

private _init() {
AuthService.CURRENT_USER = this.databaseService
.getItem(DatabaseService.KEYS.currentUser);
this.logService.debug(`Current user: `,
AuthService.CURRENT_USER);
this._notifyState(!!AuthService.CURRENT_USER);
}

private _notifyState(auth: boolean) {
this.authenticated$.next(auth);
}
}

We have a few interesting things going on here. We are putting two other services we designed to work right away, LogService and DatabaseService. They are helping us check whether a user was saved/authenticated as well as log that result.

We are also calling on a private _init method when our service gets constructed via Angular's dependency injection system. This allows us to immediately check whether an authenticated user exists in our persistent store. Then, we call a private reusable method _notifyState, which will emit true or false on our authenticated$ observable. This will provide a nice way for other components to easily get notified when the auth state changes by subscribing to this observable. We have made _notifyState reusable because our login and register methods (to be implemented in the future) will be able to use it when the results are returned from modals we may display in the UI.

We can now easily add AuthService to our PROVIDERS and we don't need to do anything else to ensure it's added to our CoreModule because our PROVIDERS are already added to the CoreModule. 

All we need to do is modify app/modules/core/services/index.ts and add our service:

import { AuthService } from './auth.service';
import { DatabaseService } from './database.service';
import { LogService } from './log.service';

export const PROVIDERS: any[] = [
AuthService,
DatabaseService,
LogService
];

export * from './auth.service';
export * from './database.service';
export * from './log.service';

WAIT! There is one important thing we want to do to ensure our AuthService initializes!

Angular's dependency injection system will only instantiate a service that is injected somewhere. Although we have all our services specified as providers in our CoreModule, they will not actually be constructed until they are injected somewhere!

Open app/app.component.ts and replace its contents with this:

// angular
import { Component } from '@angular/core';

// app
import { AuthService } from './modules/core/services';

@Component({
selector: 'my-app',
templateUrl: 'app.component.html',
})
export class AppComponent {

constructor(private authService: AuthService) { }

}

We inject our AuthService by specifying it as an argument to our component's constructor. This will cause Angular to construct our service. All subsequent injects throughout our code will all receive the same singleton. 

主站蜘蛛池模板: 凯里市| 太谷县| 南木林县| 庐江县| 太保市| 称多县| 西畴县| 中牟县| 全州县| 长兴县| 环江| 突泉县| 长葛市| 九江县| 桦南县| 家居| 永丰县| 正阳县| 修武县| 克东县| 峨眉山市| 襄樊市| 龙里县| 光泽县| 吐鲁番市| 青海省| 庆元县| 清丰县| 平陆县| 正安县| 岢岚县| 栾川县| 兰坪| 获嘉县| 化德县| 马尔康县| 前郭尔| 尉氏县| 大石桥市| 内丘县| 界首市|