How to get an Observable to return an array of transformed items (Rxjs)

Viewed 19332

I have an endpoint that produces a json list of products. I have a custom class type defined in my code for Products. I'm trying to get the data from the endpoint and have the json array of products transformed into an array of the Product class.

Sample API json (simplified from my actual data):

{
    "products": [{
        "id": 1,
        "name": "Product 1",
        "materials": [{
            "id": 100,
            "desc": "wood"
        }, {
            "id": 101,
            "desc": "metal"
        }]
    }, {
        "id": 2,
        "name": "Product 2",
        "materials": [{
            "id": 100,
            "desc": "wood"
        }, {
            "id": 102,
            "desc": "brick"
        }]
    }]
}

My code:

loadProducts(){
    this.fetchProducts().subscribe(data => {
            console.log("the data:", data);
        })
}


fetchProducts(): Observable<Product[]> {
    return this.http.get("http://example.com/mydata.json")
        .map((response) => {
            const products = (response.json()).products;
            console.log("Converting to json" + products.length);
            return products;
        })
        .map( data => {
            console.log("Working on data: ", data);
            return new Product(data.id, data.name, data.materials);
        });

What I would expect to see in my console is..

"Converting to json 2"
"Working on data: " [object]
"Working on data: " [object]
"the data:" [object,object]

.. but what I am seeing is..

"Converting to json 2"
"Working on data: " [object,object]
"the data:" [object,object]

I thought that the .map function would run for each item sent to it. I can see that when I first call .map that it is being run once on the one item (the response) that it has -- and I know that there are products 2 items being returned. I would expect the second map function to then be run twice - once for each product item. Instead it seems that it's called once being passed in the array of products.

To make matters more complicated I want to also convert the list of materials into a Material class type I've created. I know I could do all of this with forEach loops, but I want to do this the "React" way.

2 Answers
Related