首页 > 解决方案 > 如何返回 CustomType 而不是 HttpEvent来自 HTTP GET 调用?

问题描述

我有一个发送请求并接收一些用户的服务,如浏览器控制台中所示:

HTTP event: 
{_embedded: {…}, _links: {…}, page: {…}}
_embedded: {userModelList: Array(4)}
_links: {self: {…}}
page: {size: 5, totalElements: 4, totalPages: 1, number: 0}
__proto__: Object
user.service.ts:49 HTTP response: 
{_embedded: {…}, _links: {…}, page: {…}}
_embedded: {userModelList: Array(4)}
_links: {self: {…}}
page: {size: 5, totalElements: 4, totalPages: 1, number: 0}
__proto__: Object

记录器在方法中:

public getSome(searchTerm: string, sortFieldName: string, sortDirection: string, currentPage: number, pageSize: number): Observable<HateoasPageable> {
  let httpParams = new HttpParams()
  .set('page', currentPage.toString())
  .set('size', pageSize.toString());
  if (searchTerm) {
    httpParams = httpParams.append('searchTerm', searchTerm);
  }
  if (sortFieldName && sortDirection) {
    httpParams = httpParams.append('sort', sortFieldName + ',' + sortDirection);
  }
  return this.httpService.get<HateoasPageable>(this.usersUrl, httpParams)
  .pipe(
    tap((httpEvent: HttpEvent<HateoasPageable>) => console.log('HTTP event:', httpEvent)),
    map((httpEvent: HttpEvent<HateoasPageable>) => {
      return httpEvent as HttpResponse<HateoasPageable>;
    }),
    tap((httpResponse: HttpResponse<HateoasPageable>) => console.log('HTTP response:', httpResponse)),
    map((httpResponse: HttpResponse<HateoasPageable>) => {
      return httpResponse.body as HateoasPageable;
    })
  );
}

它使用 get 方法:

export class HttpService {

    constructor(private httpClient: HttpClient) { }

    public get<T>(url: string, httpParams?: HttpParams, headers?: HttpHeaders): Observable<HttpEvent<T>> {
        let options = this.buildOptions(headers);
        options = this.addOptionParams(options, httpParams);
        return this.httpClient.get<T>(url, options);
    }

但是httpResponse.body返回一个未定义的组件:

getUsers(searchTerm: string, sortFieldName: string, sortDirection: string, currentPageNumber: number): Observable<UsersApi> {
  return this.userService.getSome(searchTerm, sortFieldName, sortDirection, currentPageNumber, this.elementsPerPage)
    .pipe(
      map((hateoasPageable: HateoasPageable) => {
        console.log(hateoasPageable);
        return new UsersApi(
          hateoasPageable._embedded.userModelList as User[],
          hateoasPageable.page.pageNumber,
          hateoasPageable.page.pageSize,
          hateoasPageable.page.totalElements,
          hateoasPageable.page.totalPages
        );
      })
    );
}

自定义类:

export class HateoasPageable {

  _embedded: any = {};
  _link: any = {};
  page: HateoasPage = new HateoasPage(0, 0, 0, 0);

  constructor(_embedded: any, _link: any, page: HateoasPage) {
    this._embedded = _embedded;
    this._link = _link;
    this.page = page;
  }
}

返回的 observable 的订阅在组件中进一步完成:

merge(this.updateEvent, this.searchTermEvent, this.sort.sortChange, this.paginator.page)
  .pipe(
    startWith({}),
    switchMap(() => {
      this.isLoadingResults = true;
      let pageIndex: number = 0;
      pageIndex = this.paginator.pageIndex;
      return this.getUsers(this.searchTerm, this.sort.active, this.sort.direction, pageIndex);
    }),
    map((usersApi: UsersApi) => {
      this.isLoadingResults = false;
      this.isRateLimitReached = false;
      this.currentPageNumber = usersApi.currentPageNumber;
      this.elementsPerPage = usersApi.elementsPerPage;
      this.totalElements = usersApi.totalElements;
      this.totalPages = usersApi.totalPages;
      return usersApi.users;
    }),
    catchError(() => {
      this.isLoadingResults = false;
      this.isRateLimitReached = true;
      return observableOf([]);
    })
  ).subscribe((users: User[]) => {
    this.dataSource.data = users;
  });

控制台日志显示该httpResponse对象看起来像一个HateoasPageable实例。所以我希望改变说法:

return httpResponse.body as HateoasPageable;

进入声明:

return httpResponse as HateoasPageable;

但是,编译器抱怨错误:

Conversion of type 'HttpResponse<HateoasPageable>' to type 'HateoasPageable' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

如果我只是有这样的声明:

return httpResponse;

然后编译器抱怨错误:

Type 'Observable<HttpResponse<HateoasPageable>>' is not assignable to type 'Observable<HateoasPageable>'.

我现在面临这个问题,因为我激活了严格模式:

  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "alwaysStrict": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,

我在 Angular 8.1.3 下

标签: angularrxjs

解决方案


要发送 GET 请求并从响应正文中获取对象,您只需订阅以下get方法HttpClient

constructor(private http: HttpClient) {
}
...
this.http.get(someUrl).subscribe(response => {
    console.log(response);  // here `response` is the object from the response body
});

如果您有响应对象的接口,则可以使用通用版本的get方法:

this.http.get<HateoasPageable>(someUrl).subscribe((data: HateoasPageable) => {
    console.log(data);  // here `data` is the object from the response body
});

HttpClient你可以在angular.io找到更多关于 Angular的信息


推荐阅读