问题
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