转换为函数时无法编译代码

时间:2018-08-15 06:49:44

标签: typescript angular6 rxjs6

我有以下一段正确运行的代码。

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <PlatformTarget>x64</PlatformTarget>
</PropertyGroup>

由于我可以重用部分代码,因此我想创建一个函数,但是现在遇到编译错误。我找不到错误所在。

新功能是

  public createData(data:Data):Observable<any>{
    console.log('contacting server at '+this.API_URL +this.NEW_DATA_URL +" with data "+data+ " with httpOptions "+httpOptions.withCredentials + ","+httpOptions.headers );

let newData = new Data(data)    
    let body = JSON.stringify(newQuestion); 
//I WANT TO MOVE THE CODE BELOW INTO A FUNCTION BUT AM GETTING COMPILATION ERROR
    this.loaderService.show();
    return this.http.post(this.NEW_QUESTION_URL,body,httpOptions)
      .pipe(tap(response => { 
        let httpEvent = <HttpEvent<any>>response;
        if(httpEvent.type === HttpEventType.Response)
        {
          console.log('response from backend service:', response);

          return result;
        }
        else {
          console.log("not an http response")
          return response;
        }
      })
      ,catchError(this.handleError)
        ,finalize(()=> this.loaderService.hide())); //error handler if Observable fails

  }

ERROR是 private sendMessage(url:string, body:any,httpOptions:any){ this.loaderService.show(); return this.http.post(url,body,httpOptions) .pipe(tap(response => { let httpEvent = <HttpEvent<any>>response; //ERROR HERE - 'ArrayBuffer' cannot be converted to type 'HttpEvent<any>'. if(httpEvent.type === HttpEventType.Response) { console.log('response from backend service:', response); let result = <HttpResponse<any>>response; return result; } else { console.log("not an http response") return response; } }) ,catchError(this.handleError) ,finalize(()=> this.loaderService.hide())); //error handler if Observable fails } ERROR in src/app/web-to-backend-interface.service.ts(264,27): error TS2352: Type 'ArrayBuffer' cannot be converted to type 'HttpEvent<any>'. Type 'ArrayBuffer' is not comparable to type 'HttpUserEvent<any>'.

Property 'type' is missing in type 'ArrayBuffer'.有几个重载方法,其中一个返回Observable-angular.io/api/common/http/HttpClient#post。如何使Angular使用返回http.post的重载版本?我更改了代码并添加了Observable<T>,但这还是没有用

responseType:'json'

我看到的错误是

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
  withCredentials: true, 
observe: 'response' as 'response', 
  responseType: 'json' 
};


let observable:Observable<HttpEvent<any>> = this.http.post(url,body,httpOptions)
    return observable.pipe(tap((httpEvent:HttpEvent<any>) => {....}

为什么对工作代码进行单独的功能使其无法编译?我怎么了?

2 个答案:

答案 0 :(得分:0)

虽然我不能回答为什么以前不出现错误,但是我可以建议您如何摆脱它(假设代码在重构之前已经正常工作)。如果在声明中为response提供类型,则不会获得必须尝试映射的假定类型:

.pipe(tap((response: HttpEvent<any>) => { 

      let httpEvent = response; // No need for type-casting here anymore.

答案 1 :(得分:0)

我能够解决它,但现在我所面临的问题比答案更多。如果有人可以向我解释这种行为,将不胜感激。

我正在使用以下httpOptions对象

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' }),

withCredentials: true, 
observe: 'response' as 'response', 

};

在代码的某些位置按如下方式使用它。

 return this.http.post(this.SIGNUP_USER_URL,body,httpOptions)

这行得通。

然后,我想到将http.post更改为函数sendMessage(如问题所述),并仅在一次替换(请记住我在多个地方都使用this.http.post,想在一开始就尝试一下)。我注意到使用httpOptions会使post返回Observable<ArrayBuffer>

疑问1-为什么?

然后我将httpOptions更改为

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' }),

withCredentials: true, 
observe: 'response' as 'response', 
responseType:'json'  
};

在我直接使用http.post的地方(没有sendMessage的地方,开始出现错误。错误是

ERROR in src/app/web-to-backend-interface.service.ts(81,71): error TS2345: Argument of type '{ headers: HttpHeaders; withCredentials: boolean; observe: "response"; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
  Types of property 'observe' are incompatible.
    Type '"response"' is not assignable to type '"body"'.
src/app/web-to-backend-interface.service.ts(112,52): error TS2345: Argument of type '{ headers: HttpHeaders; withCredentials: boolean; observe: "response"; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
  Types of property 'observe' are incompatible.
    Type '"response"' is not assignable to type '"body"'.
src/app/web-to-backend-interface.service.ts(196,73): error TS2345: Argument of type '{ headers: HttpHeaders; withCredentials: boolean; observe: "response"; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
src/app/web-to-backend-interface.service.ts(216,72): error TS2345: Argument of type '{ headers: HttpHeaders; withCredentials: boolean; observe: "response"; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
src/app/web-to-backend-interface.service.ts(251,54): error TS2345: Argument of type '{ headers: HttpHeaders; withCredentials: boolean; observe: "response"; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
src/app/web-to-backend-interface.service.ts(291,9): error TS2322: Type 'Observable<ArrayBuffer>' is not assignable to type 'Observable<HttpEvent<any>>'.
  Type 'ArrayBuffer' is not assignable to type 'HttpEvent<any>'.
    Type 'ArrayBuffer' is not assignable to type 'HttpUserEvent<any>'.
      Property 'type' is missing in type 'ArrayBuffer'.

因此,我从responseType:'json'中删除了httpOptions,并在有效的this.http.post的{​​{1}}中添加了一个明确的对象!

sendMessage

observe和responseType之间似乎存在关系。例如,observe = body和responseType = text表示帖子应观察(查看)正文,将其解释为文本并返回Observable。但是我不知道为什么我不能更改private sendMessage(url:string, body:any,httpOptions){ ... let observable:Observable<HttpEvent<any>> = this.http.post(url,body,{ headers: new HttpHeaders({ 'Content-Type': 'application/json' }), withCredentials: true, observe: 'events', responseType: 'json' }) ... }