angular typescript中的Find/Filter函数抛出错误



我正试图使用angular typescript通过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函数,但还是一样,非常感谢您的帮助。

不要订阅您的服务!

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))
);
}

根据您需要在组件中做什么,如果您利用模板中的异步管道,您甚至可能不需要在那里订阅。让我们定义几个不同的可观察性$,这样就更容易看到发生了什么

我们可以使用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>

异步管道很好,因为它会自动为您订阅/取消订阅。

您正试图在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);
})

可观察项可以使用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);
}

最新更新