我正在尝试使用角度打字稿通过ID查找记录,这是我在下面给出的数组
{
"products": [
{
"id": "1731002618",
"imageUrl": "product_1.jpg",
"brand": "Max Home Collection",
"title": "5.2 cu. ft. High-Efficiency Stackable Front-Load Washer in White",
"model": "7L12X165/8045CL",
"rating": 3,
"price1": 34.00,
"cuom1": "case",
"price2": 1.97,
"cuom2": "sq. ft.",
"saving": 22,
"was": 41.48,
"addToCart": "addToCart",
"badges": [
"badge-ECO",
"badge-NLP",
"badge-SB",
"badge-ES"
]
},
{
"id": "1911002437",
"imageUrl": "product_1.jpg",
"brand": "Max Home Collection",
"title": "5.2 cu. ft. High-Efficiency Stackable Front-Load Washer in White",
"model": "7L12X165/8045CL",
"price1": 34.00,
"cuom1": "case",
"promo": "+25% Off Select Products",
"addToCart": "viewDetails"
},
{
"id": "1661232636",
"imageUrl": "product_1.jpg",
"brand": "Max Home Collection",
"title": "5.2 cu. ft. High-Efficiency Stackable Front-Load Washer in White",
"model": "7L12X165/8045CL",
"price1": 41.48,
"cuom1": "case",
"price2": 2.40,
"cuom2": "sq. ft.",
"addToCart": "viewDetails"
},
{
"id": "1231002635",
"imageUrl": "product_1.jpg",
"brand": "Max Home Collection",
"title": "5.2 cu. ft. High-Efficiency Stackable Front-Load Washer in White",
"model": "7L12X165/8045CL",
"rating": 4,
"price1": 41.48,
"cuom1": "case",
"addToCart": "viewDetails"
},
{
"id": "1561002634",
"imageUrl": "product_1.jpg",
"brand": "Max Home Collection",
"title": "5.2 cu. ft. High-Efficiency Stackable Front-Load Washer in White",
"model": "7L12X165/8045CL",
"rating": 4,
"addToCart": "viewDetails"
},
{
"id": "1781002633",
"imageUrl": "product_1.jpg",
"brand": "Max Home Collection",
"title": "5.2 cu. ft. High-Efficiency Stackable Front-Load Washer in White",
"model": "7L12X165/8045CL",
"price1": 41.48,
"cuom1": "case",
"addToCart": "viewDetails"
},
{
"id": "1121002632",
"imageUrl": "product_1.jpg",
"brand": "Max Home Collection",
"title": "5.2 cu. ft. High-Efficiency Stackable Front-Load Washer in White",
"model": "7L12X165/8045CL",
"price1": 41.48,
"cuom1": "case",
"addToCart": "addToCart"
},
{
"id": "1461002631",
"imageUrl": "product_1.jpg",
"brand": "Max Home Collection",
"title": "5.2 cu. ft. High-Efficiency Stackable Front-Load Washer in White",
"model": "7L12X165/8045CL",
"price1": 41.48,
"cuom1": "case",
"addToCart": "viewDetails"
}
]
}
我正在做这样的事情
getProductByID(postid:string):Product {
this.http.get<Product[]>(this.configUrl).subscribe(data => {
this.product=data;
});
// return this.http.get<Product[]>(this.configUrl);
return { ...this.product.find(p=>p.id===postid) };
}
ngOnInit() {
this.route.paramMap.subscribe((paramMap)=>{
if(paramMap.has("postid")) {
alert('differentiate '+paramMap.get("postid"));
alert('before call');
var p = this.Service.getProductByID(paramMap.get("postid"))
.subscribe(data=>{ console.log(data);});
})
}
它说find函数出错,我也尝试了filter函数,但是仍然一样, 非常感谢您的帮助。
答案 0 :(得分:1)
可观察变量可以使用toPromise()转换为Promise:
ngOnInit() {
this.route.paramMap.subscribe((paramMap)=>{
if(paramMap.has("postid")) {
alert('differentiate '+paramMap.get("postid"));
alert('before call');
const product = await this.Service.getProductByID(paramMap.get("postid"));
console.log('product is',product);
})
}
async getProductByID(postid:string):Promise<Product>
{
const products = await this.http.get<Product[]>(this.configUrl).toPromise();
return products.find(product=>product.id===postid);
}
答案 1 :(得分:1)
您正在尝试在this.product
上运行find。可观察变量是异步的,因此您的返回将在this.product=data
运行之前发生。
您将需要将其作为可观察者返回,并在其他地方订阅
getProductByID(postid:string):Observable<Product> { // Not actually sure if this is returning a product or not, its an Observable of something...
this.http.get<Product[]>(this.configUrl)pipe(map(data => {
this.product=data;
return { ...this.product.find(p=>p.id===postid) };
})
);
}
// Then when you need to call this method...
this.getProductByID('someId').subscribe(data => {
// this will be `{ ...this.product.find(p=>p.id===postid) };`
console.log(data);
})
答案 2 :(得分:1)
不订阅您的服务!
您的getProductsByID()
方法应定义http调用和返回所需形状所需的数据转换。您应该返回一个可观察的对象,并让服务的使用者订阅它。
通过.pipe()
方法,您可以使用各种运算符来转换流中的值。在这种情况下,您可以使用map()
运算符将传入的产品数组映射到单个产品(如果该产品不存在,则为未定义)。
服务:
// Returns an observable stream that emits a single
// product (after receiving the entire product
// list and filtering down to one by postid)
getProductByID(postid:string):Observable<Product|undefined> {
return this.http.get<Product[]>(this.configUrl).pipe(
map(products => products.find(p => p.id === postid))
);
}
根据您需要在组件中执行的操作,如果您利用模板中的async pipe,甚至可能不需要在其中进行订阅。让我们定义几个不同的Observable $,以便更轻松地了解正在发生的事情。
我们可以使用ActivatedRoute
来获取参数作为可观察的源。
组件:
postid$: Observable<string>;
product$: Observable<Product>;
constructor(private route:ActivatedRoute) { }
ngOnInit() {
// Stream that emits the latest value of postid.
// Doesn't emit if the value is null/undefined.
postid$ = route.params.pipe(
map(p => p.postid),
filter(p => !!p)
);
// Stream that emits the latest value of product. Takes
// value of postid$ and uses it to make http call.
product$ = postid$.pipe(
switchMap(postid => this.Service.getProductByID(postid)),
tap(product => console.log('product:', product))
);
}
您可以使用tap
运算符执行副作用类型的操作,也可以仅登录控制台。
在您的模板中:
<div *ngIf="product$ | async as product">
<h1>{{ product.title }}</h1>
<p>Model:{{ product.model }}</p>
<p>Price:{{ product.price }}</p>
<img src="{{ product.imageUrl }}">
</div>
异步管道非常好,因为它将自动为您订阅/取消订阅。