所以我从我的asp.net core
api获得了以下JSON结构:
{
"contentType": null,
"serializerSettings": null,
"statusCode": null,
"value": {
"productName": "Test",
"shortDescription": "Test 123",
"imageUri": "https://bla.com/bla",
"productCode": null,
"continuationToken": null
}
}
我有以下的typescript函数调用API来获得上述响应:
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;
});
}
ProductVM:
export interface ProductVM {
productName: string;
shortDescription: string;
imageUri: string;
productCode: string;
continuationToken: string;
}
我的问题是我无法将其反序列化为ProductVM
。控制台日志只生成[object Object]
如何将json响应中value
的内容实际映射到ProductVM
对象?
在地图函数中说data
是ProductVM
是不对的?我尝试了很多不同的组合,但我无法让它发挥作用!
我不确定我是否能够以某种方式自动告诉angular
将json
响应中的值数组映射到ProductVM
对象,或者我是否应该为{{ProductVM
提供构造函数1}} class(它现在是一个接口),并手动提取json
中的特定值?
答案 0 :(得分:4)
链接到http的map方法中的data
对象被视为Object
类型的对象。此类型没有您需要访问的value
成员,因此类型检查器对此不满意。
键入的对象(不是any
)只能分配给非类型对象或完全相同类型的对象。此处,您的数据类型为Object
,无法分配给ProductVM
类型的其他对象。
绕过类型检查的一种解决方案是将数据对象转换为any
无类型对象。这将允许访问任何方法或成员,就像普通的旧Javascript一样。
getProductExternal(code: string): Observable<ProductVM> {
return this.http.get("api/product?productCode=" + code)
.map((data: any) => this.externalProduct = data.value);
}
另一种解决方案是更改您的API,以便数据可以使用data.json()
传递其内容。这样,您就不必绕过类型检查,因为json()方法返回一个无类型值。
请小心,因为如果您将来添加any
对象,ProductVM
对象将没有new ProductVM()
的方法。您需要手动创建一个包含Object.assign
和var test = $('#demo5').btnSwitch({
Theme: 'Swipe',
OnText: "Active",
OffText: "Inactive",
ToggleState: true,
OnValue: true,
OffValue: false,
OffCallback: function (val) {
alert('you selected ' + val);
},
OnCallback: function(val) {
alert('you selected ' + val);
}
});
的实例才能访问这些方法。
答案 1 :(得分:1)
response
因此,首先我们将响应转换为JSON。
我将它存储到value
只是为了让它更清洁。然后,我们必须导航到value
,因为在您的数据中ProductVM
是与getProductExternal(code: string): Observable<ProductVM> {
return this.http.get(`api/product?productCode=${code}`)
.map(data => <ProductVM>data)
.catch((error: any) => Observable.throw(error.json().error || 'Server error'));
}
对应的对象。
我会这样做:
<强>服务强>
this.subscription = this.myService.getProductExternal(code).subscribe(
product => this.externalProduct = product,
error => console.warn(error)
);
<强>组件强>
{{1}}
答案 2 :(得分:1)
您是否尝试过更换
this.externalProduct = data;
与
this.externalProduct = data.json();
希望有所帮助
答案 3 :(得分:1)
From angular documentation: Typechecking http response
使用新的httpClient时必须设置返回数据的类型(因为角度为4.3)=&gt; this.http.get&LT;的 ProductVM 强>&GT;(...
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;
});
}
因此,打字稿应该让你安静下来
答案 4 :(得分:0)
我在使用该方法的客户端中使用了这种方法
HttpClient.get<GENERIC>(...).
现在它正在工作。无论如何,我不明白,如果我不使用上面答案中提供的解决方案,为什么我没有收到来自HTTP客户端的T型消息。
这里是客户:
// get
get<T>(url: string, params?: [{key: string, value: string}]): Observable<T> {
var requestParams = new HttpParams()
if (params != undefined) {
for (var kvp of params) {
params.push(kvp);
}
}
return this.httpClient.get<T>(url, {
observe: 'body',
headers: this.authHeaders,
params: requestParams
}).pipe(
map(
res => <T>res
)
);
}