可观察的异步管道不返回值
Observable Async Pipe Not Returning Values
编辑:DEMO OF THE NON-WORKING CODE
我在对可观察对象使用异步管道时遇到问题。它在一个应用程序中有效,但在另一个应用程序中无效。
可以在这里找到工作的:https://stackblitz.com/edit/angular-ry1dev
非工作代码:
products.component.ts:
export class ProductsComponent implements OnInit {
products$: Observable<Product[]>;
//NOTE: this service is coming from Akita state management
constructor( private productService: ProductService ) {}
ngOnInit() {
this.products$ = this.productService.getProducts();
}
}
products.service.ts(秋田县管理):
@Injectable({ providedIn: 'root' })
export class ProductService {
constructor( private prodStore: ProductStore, private prodService: ProductsService ) {}
getProducts() {
return this.prodService.getProducts().pipe(
tap( result => {
let dataArr = [];
for (let obj in result) {
dataArr.push(result[obj]);
}
this.prodStore.add(dataArr)
})
)
}
}
products.service.ts(上面prodService调用的http):
getProducts() {
return this.http.get<Product[]>(`${this.API}/products`);
}
products.component.html:
<mat-accordion *ngIf="products$" class='product-accordion'>
<mat-expansion-panel *ngFor="let product of products$ | async">
<mat-expansion-panel-header>
SKU: {{ product.sku }}
</mat-expansion-panel-header>
<p>${{ product.price }}</p>
<p>{{ product.description }}</p>
</mat-expansion-panel>
</mat-accordion>
上述应用的商店和查询组件与 stackblitz 相同。
我应该得到一个产品列表,例如 stackblitz 中的待办事项列表,但它在 HTML 中出错:
ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
为什么它在 stackblitz 上有效,但在我的应用程序中却无效?
您能检查一下您的后端的实际响应是什么吗?
您的前端假设是获取一个数组,但您的后端似乎正在响应类似这样的内容:
{
"something": {},
"something": {}
}
响应应该是一个数组,如下所示:
[
"something": {},
"something": {}
]
编辑:
如果我们不能改变后端行为。然后我们需要将我们的 getProducts 方法更新为 return 我们的异步产品绑定所需要的。
getProducts() {
return this.prodService.getProducts().pipe(
map( result => {
let dataArr = [];
for (let obj in result) {
dataArr.push(result[obj]);
}
this.prodStore.add(dataArr);
return dataArr;
})
)
}
问题是下面的代码returns一个对象:
getProducts() {
return products;
}
并且 ngFor 仅支持可迭代 对象,例如数组。
如果你想走秋田之路,你应该获取产品,更新商店并在组件中查询它:
this.products$ = this.productsQuery.selectAll();
编辑:DEMO OF THE NON-WORKING CODE
我在对可观察对象使用异步管道时遇到问题。它在一个应用程序中有效,但在另一个应用程序中无效。
可以在这里找到工作的:https://stackblitz.com/edit/angular-ry1dev
非工作代码:
products.component.ts:
export class ProductsComponent implements OnInit {
products$: Observable<Product[]>;
//NOTE: this service is coming from Akita state management
constructor( private productService: ProductService ) {}
ngOnInit() {
this.products$ = this.productService.getProducts();
}
}
products.service.ts(秋田县管理):
@Injectable({ providedIn: 'root' })
export class ProductService {
constructor( private prodStore: ProductStore, private prodService: ProductsService ) {}
getProducts() {
return this.prodService.getProducts().pipe(
tap( result => {
let dataArr = [];
for (let obj in result) {
dataArr.push(result[obj]);
}
this.prodStore.add(dataArr)
})
)
}
}
products.service.ts(上面prodService调用的http):
getProducts() {
return this.http.get<Product[]>(`${this.API}/products`);
}
products.component.html:
<mat-accordion *ngIf="products$" class='product-accordion'>
<mat-expansion-panel *ngFor="let product of products$ | async">
<mat-expansion-panel-header>
SKU: {{ product.sku }}
</mat-expansion-panel-header>
<p>${{ product.price }}</p>
<p>{{ product.description }}</p>
</mat-expansion-panel>
</mat-accordion>
上述应用的商店和查询组件与 stackblitz 相同。
我应该得到一个产品列表,例如 stackblitz 中的待办事项列表,但它在 HTML 中出错:
ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
为什么它在 stackblitz 上有效,但在我的应用程序中却无效?
您能检查一下您的后端的实际响应是什么吗? 您的前端假设是获取一个数组,但您的后端似乎正在响应类似这样的内容:
{
"something": {},
"something": {}
}
响应应该是一个数组,如下所示:
[
"something": {},
"something": {}
]
编辑: 如果我们不能改变后端行为。然后我们需要将我们的 getProducts 方法更新为 return 我们的异步产品绑定所需要的。
getProducts() {
return this.prodService.getProducts().pipe(
map( result => {
let dataArr = [];
for (let obj in result) {
dataArr.push(result[obj]);
}
this.prodStore.add(dataArr);
return dataArr;
})
)
}
问题是下面的代码returns一个对象:
getProducts() {
return products;
}
并且 ngFor 仅支持可迭代 对象,例如数组。
如果你想走秋田之路,你应该获取产品,更新商店并在组件中查询它:
this.products$ = this.productsQuery.selectAll();