Angular 5-如何在http调用中链接可观察对象?

时间:2018-07-31 11:08:25

标签: angular typescript observable

我正在用Angular 5编写一个应用程序,我想将原始的http调用保留在自己的服务中,以便其他服务可以根据需要操纵响应。 例如,我将拥有一个组件,组件服务和组件数据服务。

如何用这种模式将我的可观察物链接起来?这是我尝试过的:

licenseData.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpParams, HttpErrorResponse } from '@angular/common/http';
import { CONSTANT } from '../../environment/constants';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/throw';

@Injectable()
export class LicenseDataService {

    constructor(private http: HttpClient) {}

    getLicenseInfo() {

        const params = new HttpParams()
            .set('unsername', 'swapp')
            .set('comment', "hi");

        const endpoint = '/myendpoint';

        return this.http
            .get(endpoint, {params: params})
            .map((response) => {
                console.log(' response ', response);
                //return Observable.of<any>(response);
                return response['data'];
            })
            .catch(this.errorHandler);
    }

    errorHandler(error: HttpErrorResponse) {
        //TODO: log the error here
        return Observable.throw(error);
    }

}

license.service.ts

import { Injectable } from '@angular/core';
//import { Observable } from 'rxjs/Observable';
import { LicenseDataService } from './licenseData.service';

@Injectable()
export class LicenseService {

    constructor(private licenseDataService: LicenseDataService) { }

    getVersion() {

        //handle the error in here and the loading as well

        return this.licenseDataService.getLicenseInfo()
            .subscribe((response) => {
                return response['versionNumberField'];
            });
        //console.log(' result ', result);

        //return result['versionNumberField'];
    }

}

这是我的组件代码的一部分:

export class AboutComponent implements OnInit {

    //version: Observable<string>;
    version: string;

    constructor(private licenseService: LicenseService) {
        console.log('Hello Component');
    }

    ngOnInit() {
        console.log('ngOnInit');

        //this.version = this.licenseService.getVersion();

        this.licenseService.getVersion()
           .subscribe(response => this.version = response);
    }

}

我的项目无法建立。如何正确链接?

2 个答案:

答案 0 :(得分:0)

您无法订阅Subscribtion对象。

您已获得此代码 LicenseDataService:

return this.licenseDataService.getLicenseInfo()
            .subscribe((response) => {
                return response['versionNumberField'];
            });

,然后在LicenseService中,尝试订阅已经是Subscribtion的LicenseDataService返回的内容。选项之一是在LicenseService中使用map,然后在Component中订阅。

  return this.licenseDataService.getLicenseInfo()
            .map((response) => {
                return response['versionNumberField'];
            });

此后,您在组件中的subscribe应该可以工作。

我个人将只接受一项服务-这些操作并不那么复杂。

答案 1 :(得分:0)

除非绝对必要,否则您不想在服务内部管理订阅。

如果您是我,那么我会将HTTP服务公开为可观察的并使用共享重播,以便在您通过应用程序的生命周期订阅a​​ppVersion时它共享结果。这样,您就不会在服务内部拥有内部订阅,这是一种代码味道。

    @Injectable()
    export class LicenseService {


          private _appVersion$;

          get appVersion$(){
              if(!this_appVersion$){
                this._appVersion$ = this.getVersion().pipe(shareReplay());   
              }
              return this._appVersion$;
          }

          private getVersion() {

        //handle the error in here and the loading as well

            return this.licenseDataService.getLicenseInfo()
               .pipe(
                  map(response => return response['versionNumberField'] as any
               );
         }     
   } 

然后,在组件中,您可以注入服务并订阅可观察的appVersion $以获取应用版本值。

我这样做的原因是,它使所有内容都保持在更具响应性的编程范例中,并允许您将动作与其他异步代码链接在一起。而且它在服务内部没有订阅。