Deserialisering av json i Angular 2/4 med HttpClientModule
Så jag får följande JSON-struktur från mitt asp.net core-api:
{
"contentType": null,
"serializerSettings": null,
"statusCode": null,
"value": {
"productName": "Test",
"shortDescription": "Test 123",
"imageUri": "https://bla.com/bla",
"productCode": null,
"continuationToken": null
}
}
Jag har följande TypeScript-funktion som anropar API:et för att få ovanstående svar:
public externalProduct: ProductVM;
getProductExternal(code: string): Observable<ProductVM> {
return this.http.get("api/product?productCode=" + code)
.map((data: ProductVM) => {
this.externalProduct = data; //not working...
console.log("DATA: " + data);
console.log("DATA: " + data['value']);
return data;
});
}
ProduktVM :
export interface ProductVM {
productName: string;
shortDescription: string;
imageUri: string;
productCode: string;
continuationToken: string;
}
Mitt problem är att jag inte kan deserialisera det till ProductVM. Konsolloggarna producerar bara [object Object]
Hur kan jag faktiskt mappa innehållet i value i mitt json-svar till ett ProductVM-objekt?
Är det fel att säga att data är en ProductVM i map-funktionen? Jag har försökt många olika kombinationer men jag får det inte att fungera!
Jag är osäker på om jag på något sätt automatiskt kan säga åt angular att mappa värdearrayen i json-svaret till ett ProductVM-objekt eller om jag borde tillhandahålla en konstruktor till ProductVM-klassen (det är ett gränssnitt just nu), och extrahera de specifika värdena i json manuellt?
Svar #1
data-objektet i map-metoden som kedjas till http anses vara ett Object-typat objekt. Denna typ har inte value-medlemmen som du behöver komma åt och därför är typkontrollen inte nöjd med det.
Objekt som är typade (som inte är any) kan endast tilldelas otippade objekt eller objekt av exakt samma typ. Här är dina data av typen Object och kan inte tilldelas ett annat objekt av typen ProductVM.
En lösning för att kringgå typkontroll är att casta ditt dataobjekt till ett any otippat objekt. Detta kommer att tillåta åtkomst till vilken metod eller medlem som helst precis som vanlig gammal Javascript.
getProductExternal(code: string): Observable<ProductVM> {
return this.http.get("api/product?productCode=" + code)
.map((data: any) => this.externalProduct = data.value);
}
En annan lösning är att ändra din API så att data kan leverera sitt innehåll med data.json(). På så sätt behöver du inte kringgå typkontroll eftersom json()-metoden returnerar ett otypat värde.
Var försiktig dock eftersom ditt any-objekt inte kommer att ha metoderna för ProductVM om du någonsin lägger till dem i framtiden. Du kommer att behöva manuellt skapa en instans med new ProductVM() och Object.assign på den för att få tillgång till metoderna.
Svar #2
Från Angular-dokumentationen: Typkontroll av HTTP-svar
Du måste ange typen av returnerad data när du använder ny httpClient (sedan Angular 4.3) => this.http.get<ProductVM>(...
public externalProduct: ProductVM;
getProductExternal(code: string): Observable<ProductVM> {
return this.http.get<ProductVM>("api/product?productCode=" + code)
.map((data: ProductVM) => {
this.externalProduct = data; // should be allowed by typescript now
return data;
});
}
så Typescript bör lämna dig i fred
