Estoy usando WooCommerce v3 api, mi objetivo es mostrar una lista con todas las categorías y mostrar horizontalmente todos los productos por categoría, como:
Nombre de la categoría:
producto producto1 producto2
Categoría 2 nombre:
producto producto1 producto2
pero no hay un punto final para obtener todo esto, así que obtengo todas las categorías primero con
getAllCats(): Observable<any>{ const req = this.httpS.get(`${API.prod.url+API.prod.woo+'products/categories/?consumer_key='+API.prod.consumer_key+'&consumer_secret='+API.prod.consumer_secret}`); return req; } getProductsByCat(catId: number): Observable<any>{ const req = this.httpS.get(`${API.prod.url+API.prod.woo+'products?consumer_key='+API.prod.consumer_key+'&consumer_secret='+API.prod.consumer_secret+'&category='+catId}`); return req; }y luego en mi componente estoy haciendo esto
categories: any = {}; cats: Array<any> = []; products: Array<any> = []; catsWithAllProducts: any = { category: [{ products: [] }] }; kats: Category[] = []; showAllCatsWithProducts(){ this.pService.getAllCats().subscribe((cats) => { for (const [i,cat] of cats.entries()) { this.pService.getProductsByCat(cat.id).subscribe((products) => { this.cats.push(cat); this.products.push(products); this.catsWithAllProducts.category = cat; this.kats.push(this.catsWithAllProducts); //new categories array with products }); } }); }Tengo dos problemas, los productos [] están vacíos, estoy confundido con cómo lograr crear un nuevo objeto o matriz o matriz de objetos con todos los productos dentro de una categoría. Justo lo que está impreso en pantalla son todas las categorías pero con el nombre repetido:
Tengo 10 categorías, y muestra el primer nombre que recibe * el número de categorías. Lo que he estado pensando es que primero debería ser asíncrono, quiero decir, es un observable pero está empujando a la matriz cada elemento con o sin respuesta todavía. Estoy un poco atascado aquí, gracias por leerme.
No estoy muy seguro, pero intente si esto cambia sobre su código para resolver su posible problema asíncrono:
getAllCats(): Observable<any>{ return this.httpS.get(`${API.prod.url+API.prod.woo+'products/categories/?consumer_key='+API.prod.consumer_key+'&consumer_secret='+API.prod.consumer_secret}`); } getProductsByCat(catId: number): Observable<any>{ return this.httpS.get(`${API.prod.url+API.prod.woo+'products?consumer_key='+API.prod.consumer_key+'&consumer_secret='+API.prod.consumer_secret+'&category='+catId}`); } showAllCatsWithProducts() { this.pService.getAllCats() .pipe( switchMap( cat => this.pService.getProductsByCat(cat.id) ), ) .subscribe( products => { this.cats.push(cat); this.products.push(products); this.catsWithAllProducts.category = cat; this.kats.push(this.catsWithAllProducts); }); )Recomendaría primero cambiar su servicio para definir lo que necesita como observables, ocultando la mayor complejidad posible de los componentes, así:
export interface Category { id: number; } export interface Product { id: number; } @Injectible() export class pService { readonly categories$: Observable<Category[]> = this.httpS.get(`${API.prod.url+API.prod.woo+'products/categories/?consumer_key='+API.prod.consumer_key+'&consumer_secret='+API.prod.consumer_secret}`).pipe( take(1), shareReplay() ); readonly productsPerCategory$: Observable<[Category, Product[]]> = this.categories$.pipe( mergeMap(category => this.getProductsByCat(category.id).pipe( map(products => [category, products]) )), shareReplay() ); readonly allProducts$: Observable<Product[]> = this.productsPerCategory$.pipe( mergeMap(ppc => from(ppc[1])), distinct((p: Product) => p.id), // if products overlap, otherwise remove this line if every product is in only one category. shareReplay() ); readonly allProducts: Promise<Product []> = this.allProducts$.pipe(toArray()).toPromise; private getProductsByCat(catId: number): Observable<Product[]>{ return this.httpS.get(`${API.prod.url+API.prod.woo+'products?consumer_key='+API.prod.consumer_key+'&consumer_secret='+API.prod.consumer_secret+'&category='+catId}`); } }Esto es todo sin una suscripción. Es posible que también pueda escapar sin una sola suscripción en su comentario, si usa la tubería asíncrona, según lo que necesite.
Lo manejo con async/await y cambio el método regular for a forEach en showAllCatsWithProducts()
async showAllCatsWithProducts(){ this.pService.getAllCats().subscribe((cats) => { cats.forEach(async cat => { //for each category const response = await this.pService.getProductsByCat(cat.id).subscribe(res => { //It's gonna wait por their products this.categories.push({id: cat.id,name: cat.name,slug:cat.slug, products: res}); //Push category with products }); }); }); }