Angular 使用Observable从httpClient返回字符串数组

Angular 使用Observable从httpClient返回字符串数组,angular,typescript,Angular,Typescript,我有一个API端点,它返回一个字符串数组(json),我试图创建一个页面,通过Angular服务输出内容。以下是我到目前为止的情况(我在第7页): 导出类现场服务{ 构造函数(私有httpClient:httpClient){} fieldTypesURL=http://localhost:3000/fields/types'; public getTypes():可观察{ 返回this.httpClient.get(this.fieldTypesURL) .pipe(map((响应:any)=

我有一个API端点,它返回一个字符串数组(json),我试图创建一个页面,通过Angular服务输出内容。以下是我到目前为止的情况(我在第7页):

导出类现场服务{
构造函数(私有httpClient:httpClient){}
fieldTypesURL=http://localhost:3000/fields/types';
public getTypes():可观察{
返回this.httpClient.get(this.fieldTypesURL)
.pipe(map((响应:any)=>response.json()),
catchError((error:any)=>Observable.throw(error.json().error | |'Server error'));
}
}
我得到的编译错误如下:

Type 'Observable<any[]>' is missing the following properties from type 'Promise<string[]>': then, catch, [Symbol.toStringTag], finally
类型“Observable”缺少类型“Promise”中的以下属性:然后是catch,[Symbol.toStringTag],最后是

为什么在这里提到承诺,而我试图使用一个可观察的?欢迎有任何想法

当您使用httpClient时,它会自动将响应解析为JSON。因此,
.pipe(map((response:any)=>response.json())
可能是这里的错误

另外,键入“any”更改为“string”

试一试:

public getTypes(): Observable<string[]> {
return this.httpClient.get<string[]>(this.fieldTypesURL)
  .catch((error: any) => Observable.throw(( error && JSON.parse(error).error) || 'Server error')));
}
public getTypes():可观察{
返回this.httpClient.get(this.fieldTypesURL)
.catch((error:any)=>Observable.throw((error&&JSON.parse(error.error)| |“服务器错误”));
}
.json()函数的作用几乎与这里看到的相同
@hamzakhan正确地说,我们不需要将响应解析为json。但由于您的代码仍然不起作用,请尝试这样做,我刚刚在函数getTypes()的返回类型中将Observable更改为Observable。 希望它能起作用,祝你好运

export class FieldService {
  constructor(private httpClient: HttpClient) { }

  fieldTypesURL = 'http://localhost:3000/fields/types';

  public getTypes(): Observable<any> {
    return this.httpClient.get(this.fieldTypesURL)
    .pipe(map((response: any) => console.log(response),
      catchError((error: any) => Observable.throw(( error && JSON.parse(error).error) || 'Server error')));
  }
}
导出类现场服务{
构造函数(私有httpClient:httpClient){}
fieldTypesURL=http://localhost:3000/fields/types';
public getTypes():可观察{
返回this.httpClient.get(this.fieldTypesURL)
.pipe(map((响应:any)=>console.log(响应),
catchError((error:any)=>Observable.throw((error&&JSON.parse(error.error)| |“服务器错误”));
}
}
1)使用泛型参数调用
httpClient
,可以为您进行
json
转换和类型转换

2)
Observable#throw
已被弃用,请改用
throwError
运算符。此外,请确保正确分析和处理错误。为您的错误指定一个类型肯定会提高类型安全性

3) 确保正确调用服务方法

// field.service.ts
export class FieldService {

  constructor(private httpClient: HttpClient) { }

  fieldTypesURL = 'http://localhost:3000/fields/types';

  public getTypes(): Observable<string[]> {
    return this.httpClient.get<string[]>(this.fieldTypesURL).pipe(
      catchError((r: HttpErrorResponse) => throwError(r.error || 'Server error'))
    );
  }
}
//field.service.ts
出口级现场服务{
构造函数(私有httpClient:httpClient){}
fieldTypesURL=http://localhost:3000/fields/types';
public getTypes():可观察{
返回此.httpClient.get(this.fieldTypesURL).pipe(
catchError((r:HttpErrorResponse)=>throwError(r.error | |“服务器错误”))
);
}
}
//your.component.ts
导出类组件{
建造师(专用现场服务:现场服务){}
//…组件逻辑。。。
公共类型:字符串[];
公共类型$:可见;
公共电话服务(){
//正确的电话
this.fieldService.getTypes().subscribe(类型=>this.types=types)
//这也是一个正确的调用,带有一点可观察的流处理
this.types$=this.fieldService.getTypes().pipe(
catchError((err:any)=>{
//组件端错误处理可以放在这里
回程抛掷器(err);
}),
平面图(类型=>类型),
过滤器(类型=>!!类型),
映射(type=>type.trim()),
toArray()
);
//调用不正确(编译器错误)
this.fieldService.getTypes().then(类型=>/*无论什么*/);
this.fieldService.getTypes().catch(err=>/*无论什么*/);
让r:Promise=this.fieldService.getTypes();
}
}
希望这对您有所帮助:-)

使用以下代码作为catchError(this.handleError)将处理您的错误以及失败的Http请求

export class FieldService {
  constructor(private httpClient: HttpClient) { }

  fieldTypesURL = 'http://localhost:3000/fields/types';

  public getTypes(): Observable<any[]> {
    return this.httpClient.get<any[]>(this.fieldTypesURL)
    .pipe(
      catchError(this.handleError)
    );
  }

  private handleError(error: HttpErrorResponse) {

    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.log('An error occurred:', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.log(
        `Backend returned code ${error.statusText}, ` +
        `body was: `,error.message);
    }
    // return an observable with a user-facing error message
    return _throw('Something went wrong. Please try again later.');
  };
}
导出类现场服务{
构造函数(私有httpClient:httpClient){}
fieldTypesURL=http://localhost:3000/fields/types';
public getTypes():可观察{
返回this.httpClient.get(this.fieldTypesURL)
.烟斗(
catchError(this.handleError)
);
}
私有句柄错误(错误:HttpErrorResponse){
if(error.error instanceof ErrorEvent){
//发生客户端或网络错误。请相应地进行处理。
console.log('发生错误:',error.error.message);
}否则{
//后端返回了一个不成功的响应代码。
//回应主体可能包含了错误的线索,
console.log(
`后端返回代码${error.statusText},`+
`正文为:`,错误。消息);
}
//返回带有面向用户的错误消息的可观察对象
return _-throw('出现问题,请稍后再试');
};
}

如果您注意到,我从代码中删除了.map(),只是因为它用于对响应数据执行一些操作,这是不需要的。

我想您可以跳过
管道
在这种情况下,代码似乎适合httpClient,这不是必需的响应。json()您使用的是什么版本的TypeScript?(正如在package.json文件中定义的那样)我使用的是Typescript版本:~3.2.2您显然试图将getTypes()返回值分配给您定义为Promise的内容。我删除了该行,简化了代码,最终得到了更好的版本,但我仍然遇到了完全相同的错误。我已经尝试了大量从这篇文章推荐的变体,但也没有成功:对此我深表歉意。请参见上面的.public getTypes():可观察的{返回this.httpClient.get(this.fieldTypesURL);}。。。是我当前的代码,它抛出了相同的错误。
// your.component.ts
export class YourComponent {

  constructor(private fieldService: FieldService){}

  // ... component logic ...

  public types: string[];
  public types$: Observable<string[]>;

  public callService() {

    // A correct call
    this.fieldService.getTypes().subscribe(types => this.types = types)

    // Also a correct call with a bit of observable stream processing
    this.types$ = this.fieldService.getTypes().pipe(
      catchError((err: any) => {
        // Component-side error processing can be put here
        return throwError(err);
      }),
      flatMap(types => types),
      filter(type => !!type),
      map(type => type.trim()),
      toArray()
    );

    // Incorrect calls (compiler errors)
    this.fieldService.getTypes().then(types => /* whatever */);
    this.fieldService.getTypes().catch(err => /* whatever */);
    let r: Promise<string[]> = this.fieldService.getTypes();
  }
}
export class FieldService {
  constructor(private httpClient: HttpClient) { }

  fieldTypesURL = 'http://localhost:3000/fields/types';

  public getTypes(): Observable<any[]> {
    return this.httpClient.get<any[]>(this.fieldTypesURL)
    .pipe(
      catchError(this.handleError)
    );
  }

  private handleError(error: HttpErrorResponse) {

    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.log('An error occurred:', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.log(
        `Backend returned code ${error.statusText}, ` +
        `body was: `,error.message);
    }
    // return an observable with a user-facing error message
    return _throw('Something went wrong. Please try again later.');
  };
}