在自定义HTTP服务中添加服务Angular 2

时间:2017-03-28 13:09:42

标签: angular angular2-services

我通过扩展HTTP服务使用HTTP拦截器。如果用户令牌过期,我需要捕获所有请求并触发注销事件。

注销服务在AuthService中定义,它也使用Http Service。

每当我尝试创建AuthService实例并访问其功能时,它们都会返回未定义。

我有什么遗失的吗?

http.interceptor.ts

import { Injectable, OnDestroy } from "@angular/core";
import { Router } from '@angular/router';
import { ConnectionBackend, RequestOptions, Request, RequestOptionsArgs, Response, Http, Headers} from "@angular/http";
import { Observable } from "rxjs/Rx";
import { environment } from "../environments/environment";
import { AuthService } from './services/auth.service';
import { SharedService } from './services/shared.service';
import { LoaderService } from './factory/loader.service';

import 'rxjs/add/operator/map';

@Injectable()
export class InterceptedHttp extends Http {
    private _router: Router;
    private _auth: AuthService;

    constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private loaderService: LoaderService) {
        super(backend, defaultOptions);
    }

    request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
        return super.request(url, options);
    }

    get(url: string, options?: RequestOptionsArgs): Observable<Response> {
        this.showLoader();
        url = this.updateUrl(url);
        return super.get(url, this.getRequestOptionArgs(options))
            .do((res:Response) => {
                console.log(res.json());
                let data = res.json();
                if(!data.status && (data.message == "Token has expired" || data.message == "Token is Invalid")){
                    this._auth.logout();
                }
                /*else if(!data.status && data.message == "Some Error has occured") {

                }*/
            })
            .finally(() => {
                this.onEnd();
            });
    }

    post(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {
        this.showLoader();
        url = this.updateUrl(url);
        return super.post(url, body, this.getRequestOptionArgs(options))
                .do((res:Response) => {
                    console.log(res.json());
                    let data = res.json();
                    if(!data.status && (data.message == "Token has expired" || data.message == "Token is Invalid")){
                        console.log('Logged Out While Request');
                        this._auth.logout();
                    }
                    /*else if(!data.status && data.message == "Some Error has occured") {

                    }*/
                })
                .finally(() => {
                    this.onEnd();
                });
    }

    put(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {
        url = this.updateUrl(url);
        return super.put(url, body, this.getRequestOptionArgs(options));
    }

    delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
        url = this.updateUrl(url);
        return super.delete(url, this.getRequestOptionArgs(options));
    }

    private updateUrl(req: string) {
        return  environment.API_URL + req;
    }

    private getRequestOptionArgs(options?: RequestOptionsArgs) : RequestOptionsArgs {
        if (options == null) {
            options = new RequestOptions();
        }
        if (options.headers == null) {
            options.headers = new Headers();
        }

        options.headers.append('Accept','application/json');
        options.headers.append('Content-Type', 'application/json');
        options.headers.append('device-id','123434234');
        options.headers.append('device-type','web');
        options.headers.append('Authorization','Bearer '+window.localStorage['key']);

        return options;
    }

    private onEnd(): void {
        this.hideLoader();
    }

    private showLoader(): void {
        this.loaderService.show();
    }
    private hideLoader(): void {
        this.loaderService.hide();
    }
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule,ReactiveFormsModule } from '@angular/forms';
import { HttpModule, Http, XHRBackend, RequestOptions } from '@angular/http';

import { MaterialModule } from '@angular/material';
import 'hammerjs';

import { PerfectScrollbarModule } from 'angular2-perfect-scrollbar';
import { PerfectScrollbarConfigInterface } from 'angular2-perfect-scrollbar';
import { Select2Module } from 'ng2-select2';
import { ModalModule } from "ng2-modal";
import { CustomFormsModule } from 'ng2-validation'
import { MomentModule } from 'angular2-moment';

import { AppComponent } from './app.component';
import { routing } from './app.routes';
import { httpFactory } from "./http.factory";

import { AuthService } from './services/auth.service';
import { AuthManager, AdminRole } from './authManager';
import { AppSettings } from './app.settings';
import { LoaderService } from './factory/loader.service';
import { GlobalEventService } from './factory/globalEvent.service';
import { CustomMessageService } from './factory/message.service';
import { SharedService } from './services/shared.service';

import { StaticCMSService } from './services/static.service';
import { UserService } from './services/users.service';
import { TeacherService } from './services/teacher.service';
import { StudentService } from './services/student.service';
import { ChatService } from './services/chat.service';

import { HeaderComponent } from './component/header/header.component';
import { FooterComponent } from './component/footer/footer.component';
import { LoginComponent } from './component/login/login.component';
import { NavigationComponent } from './component/navigation/navigation.component';
import { LoaderComponent } from './component/loader/loader.component';
import { CustomMessage } from './component/custom_msg/message.component';
import { DeletePopupComponent } from './component/delete_popup/delete_popup.component';

import { TeacherComponent } from './component/teacher/teacher.component';
import { ViewTeacherComponent } from './component/teacher/view/view.component';

import { StudentComponent } from './component/student/student.component';
import { ViewStudentComponent } from './component/student/view/view.component';

import { ChatComponent } from './component/chat/chat.component';
import { TermsComponent } from './component/terms/terms.component';
import { PolicyComponent } from './component/policy/policy.component';
import { FaqComponent } from './component/faq/faq.component';
import { ViewFaqComponent } from './component/faq/view/view.component';
import { AddFaqComponent } from './component/faq/add/add.component';

import { RouteRestrictedComponent } from './component/restrict/restrict.component';

import { DecimalTextPipe } from './pipe/decimal_text.pipe';

const PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = {
  suppressScrollX: true
};

@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    LoginComponent,
    FooterComponent,
    DecimalTextPipe,
    RouteRestrictedComponent,
    NavigationComponent,
    LoaderComponent,
    CustomMessage,
    DeletePopupComponent,
    TermsComponent,
    PolicyComponent,
    FaqComponent,
    ViewFaqComponent,
    AddFaqComponent,
    TeacherComponent,
    ViewTeacherComponent,
    StudentComponent,
    ViewStudentComponent,
    ChatComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    ReactiveFormsModule,
    HttpModule,
    routing,
    MaterialModule,
    MaterialModule.forRoot(),
    PerfectScrollbarModule.forRoot(PERFECT_SCROLLBAR_CONFIG),
    Select2Module,
    ModalModule,
    CustomFormsModule,
    MomentModule
  ],
  exports: [
    LoaderComponent
    ],
  providers: [
    AuthManager,
    AdminRole,
    AuthService,
    AppSettings,
    SharedService,
    LoaderService,
    CustomMessageService,
    StaticCMSService,
    GlobalEventService,
    ChatService,
    TeacherService,
    StudentService,
    UserService,
    {
        provide: Http,
        useFactory: httpFactory,
        deps: [XHRBackend, RequestOptions, LoaderService]
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

auth.service.ts

import { Injectable, OnInit } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Router } from '@angular/router'
import { Observable, BehaviorSubject } from 'rxjs/Rx';
import { AppSettings } from '../app.settings';

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/publishReplay';

@Injectable()
export class AuthService implements OnInit {
    private currentUserData: any;
    constructor(
        private _http: Http,
        private _headers: AppSettings,
        private _router: Router
    ){
    }

    ngOnInit(){
    }

    isLoggedIn(){
        if(!window.localStorage['key']){
            return false;
        }
        else {
            return true;
        }
    }

    loginAuth(creds){
        return this._http.post('login',creds).map((res:Response) => res.json()).share();
    }

    getCurrentUserDetails(){
        if(!this.currentUserData){
            this.currentUserData = this._http.get('getcurrentuserdetails').map((res:Response) => res.json());
        }
        return this.currentUserData;
    }

    logout(){
        this._http.get('logout').map((res:Response) => res.json()).subscribe(data => {
            window.localStorage.removeItem('key');
            this._router.navigateByUrl('/');
            this.currentUserData = null;
        });
    }
}

1 个答案:

答案 0 :(得分:0)

您有循环依赖:HttpInterceptor现在是此模块中的新Http服务。因此AuthService需要HttpInterceptor,反之亦然。

事实上,我认为不需要在代码中扩展Http服务。您可以创建一个类似MyHttp服务的包装器,它注入Http并使用this.http.get(...)this.http.post(...)等代替super.get(...)。并在Http中注入真实的AuthService

class HttpInterceptor{
   constructor(http:Http,auth:AuthService){}
}

class AuthService{
   constructor(http:Http){}
}

或者您可以将您的课程AuthServiceHttpInterceptor合并为一个,但缺点是每个课程都有loginlogout方法。

正如我在评论中所说,我不知道您的应用程序是如何运作的,所以我暂时无法想到任何其他方式。