使用Observables从httpClient返回字符串数组

时间:2019-02-05 04:48:22

标签: angular typescript

我有一个API端点,该端点返回一个字符串数组(json),并且我试图创建一个通过Angular Service吐出内容的页面。到目前为止,这是我所拥有的(我使用的是Angular 7):

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(map((response: 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?欢迎任何想法!

4 个答案:

答案 0 :(得分:1)

使用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')));
}

.json()函数几乎*可以与此处看到的相同 Angular Response.json() not documented

答案 1 :(得分:0)

@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')));
  }
}

答案 2 :(得分:0)

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'))
    );
  }
}
// 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();
  }
}

希望这会有所帮助:-)

答案 3 :(得分:0)

将以下代码用作 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.');
  };
}

如果您注意到了,我从代码中删除了 .map(),只是因为它被用来对响应数据进行某些操作,这不是必需的。 / p>