How to cast observable response to local object

浪子不回头ぞ 提交于 2021-02-20 19:23:52

问题


In current Angular 6 application there is a subscribe to observable (response from RESTful service)

  this.activatedRoute.data.subscribe(({bag}) => {
    console.log(bag);
    this.bag= bag;
  });

the subscription is waiting response from resolver

@Injectable({
  providedIn: 'root'
})
export class BagResolver implements Resolve<Bag> {
  constructor(private service: BagService) {}

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    const id = route.params['id'] ? route.params['id'] : null;
    if (id) {
      const existingBag = this.service.find(id).pipe(map((bag: HttpResponse<Bag>) => bag.body));
      return existingBag;
    }

    return of(new Bag());
  }
}

Ran a debug mode I found bag is an object with follow structure

Object
{headers:,
 body{id:10, name:aName, ...},  <-- this is the actual bag object
 statusCode:"OK",
 statusCodeValue:"200"
 }

So bag in the subscription is not really a bag object but looks like a http response which wrapped the bag object in its body

Now I really want to extract the body from above object and cast to local object

So then how to safely extract the data and cast the object from above return from subscribe(...)?


回答1:


I suspect that this object is a ResponseEntity from Spring and not a HttpResponse from angular. The tell is statusCodeValue which is not a property of angular's HttpResponse. If you are serializing spring ResponseEntitys and sending them as the response AND observing the response body (indirectly or directly—which all appear true here), you need to create a similar interface in the front-end and use it in your service:

interface ResponseEntity<T> {
   headers: { [headerName: string]: string },
   body: T,
   statusCode: "OK" | "SERVER_ERROR" | "BAD_REQUEST", //etc
   statusCodeValue: "200" | "500" | "400" | "404" //etc
}

Sample Service

import { ResponseEntity } from "./dir/dir/file";

class BagService {
    constructor(http: HttpClient) {}

    find(id: string): Observable<Bag> {
        return this.http.get<ResponseEntity<Bag>>(`/bag/${id}`).pipe(
            map(resp => resp.body)
        );
    }
}

I hope this helps!




回答2:


I would sugest that you don't subscribe in the TypeScript and use the async pipe in the view

bag$ = this.activatedRoute.data.pipe(
    map(res => res.body) // This will map your data to extract the body
);

in your TypeScript and in your view

<div *ngIf="bag$ | async as bag">
    {{bag | json}}
</div>

That is what the async pipe is for and you don't have to worry about managing subscriptions.




回答3:


If the response in json format then you can write directly
this.http.method(url, option).pipe(map((this.handelResponse))

handelResponse(res: Response){
    data = res.json;
    // do whatever you want
    return data // or return your object
}


来源:https://stackoverflow.com/questions/53075816/how-to-cast-observable-response-to-local-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!