Issue
My code initially worked until I needed to change the structure of my JSON object. This is my original JSON object structure, it is just a simple list of products returned by my API. I am abbreviating for brevity:
[{"PicFile":"11382","ShortDesc":"At Home Slot Machine","ActualPrice":12.99, .... }]
In my products service, I call my API and return a the list converted to my product model:
getProductsByCategory(categoryCode: string): Observable<Product[]> {
let url = this.baseAPIUrl + .....
return this.httpClient.get(url)
.pipe(
map((data: any[]) => data.map((item) => this.adapter.convert(item)))
);
}
This is my adapter code. I created a generic adapter that can take in any type of object, this is it's implementation:
import { Injectable } from "@angular/core";
import { Adapter } from "./adapter";
export class Product {
constructor(
public PicFile: string,
public ShortDesc: string,
public ActualPrice: number,
.... other properties here
) { }
}
@Injectable({
providedIn: "root",
})
export class ProductAdapter implements Adapter<Product> {
convert(item: any): Product {
return new Product(item.PicFile, item.ShortDesc, item.ActualPrice, .... );
}
}
In my products component, I am subscribing to the observable returned from the service:
loadAllProductsByCategory(categoryCode: string) {
this.loadingSubject.next(true);
this.productService.getProductsByCategory(categoryCode).pipe(
catchError(() => of([])),
finalize(() => this.loadingSubject.next(false))
)
.subscribe(products => this.productsSubject.next(products));
}
This works perfectly with my simple JSON structure. I needed to add a count property for paging purposes and will most likely be adding others in the future. The new JSON object has a property of "Data" that holds the list of products, and a property called "Count".
{"Data":[{"PicFile":"11382","ShortDesc":"At Home Slot Machine","ActualPrice":12.99, ...}], "Count":41}
So, my question is how do I change my service code to look for the "Data" property and convert it?:
return this.httpClient.get(url)
.pipe(
map((data: any[]) => data.map((item) => this.adapter.convert(item))) <-- how to look for "Data" property and convert only that list, not the whole object?
);
I have tried several things, including subscribing here but then it is converted to a subscription and I need to return the observable. I'm sure it can be done, hopefully, but I am fairly new to Angular and RxJS. I just can't seem to figure out the mapping syntax correctly.
Thank you in advance for any help you can provide, Jim
Solution
if the structure of your data returned has changed, you need to update your map
in the service.
return this.httpClient.get(url).pipe(
map( (data: any) => data.Data.map((item) => this.adapter.convert(item)) )
);
you should probably changed the property name you pass into your map to avoid confusion. i.e.
(resp: any) => resp.Data.map((item) => this.adapter.convert(item))
The structure of the data returned from the service has changed from and Array to an Object. therefore, you must change your mapping process
this updated code will only return the Data
array from your response.
if you need to also return the count, then you will need to update your service method getProductsByCategory
to return an object that includes the count as well as the data.
Answered By - Edward
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.