我有一个angular5服务,它执行HTTP get并返回一个特定类型,如下所示
public getProductByIDproductId: string): Observable<Product> {
const headers = new HttpHeaders({ "Content-Type": "application/json" });
const url = `${environment.productservice_baseurl}/${productId}`;
return this.http
.get<Product>(url, { headers: headers })
.pipe(
tap(data => (this._product = data)),
catchError(this.handleError)
);
}
Product类是一个具有属性和方法的类。下面有一小段摘录。
class Product{
productID:string;
productName:string;
setQuantity(quantity:number){
}
}
当我在get.uproduct上调用setQuantity函数时,得到'setQuantity不是函数'错误。当我尝试检查this._product的实例时,它不是Product类型,而是类型Object。
get方法上设置的泛型类型是否仅用于帮助编译时类型检查?如何从getProductByIDproductId方法获取产品类的具体实例?
答案 0 :(得分:5)
你无法做你正在做的事情。
当您从URL获取数据时,您只获得JSON。您告诉TypeScript data
类型为Product
,但这只是编译器的提示而不是真的。
data
未通过调用new Product
创建,因此它不会共享其方法。
如果您希望this._product
的行为与原生Product
实例相同,则可以执行以下操作:
this._product = data;
Object.setPrototypeOf(this._product, Product.prototype);
这样您就可以将this._product
转换为真实的Product
实例,包括其方法。
另一种选择,如果您担心setPrototypeOf
及其潜在的性能缺陷,就是这样做:
this._product = new Product();
Object.assign(this._product, data);
当然,如果Product
具有无参数构造函数,这只是一个好主意。而且,无论如何,如果data
具有未在Product
类中定义的属性,您也可能会遇到性能问题。
答案 1 :(得分:2)
您可以映射响应。
return this.http
.get<Product>(url, { headers: headers })
.map(response => new Product(response)) // I don't know your constructor
.pipe(
tap(data => (this._product = data)),
catchError(this.handleError)
);
这样,您确定您的对象将是您定义的Typescript对象。
编辑您可以手动创建对象&#34;&#34;只有几行:
export class Product {
// Your class ...
public static createProductFromHttpResponse = (response: any) => {
const ret = new Product();
for (let key in response.key) { ret[key] = response[key]; }
return ret;
}
}
在您的地图中:
.map(response => Product.createProductFromHttpResponse(response))
答案 2 :(得分:0)
据我所知,要指定响应类型,您应该使用接口而不是类,因此您的产品应该是一个接口:
interface Product{
productID:string;
productName:string;
}
因为它只是接口和http响应,所以它不应该有任何方法
修改强>
@trichetriche的回答可能就是这个问题的解决方案之一。