0

I have a HTTP service which returns me following data: (stackbitz)

[
   {
      "customerId":"114860",
      "customerName":"John Dyer",
      "dateOfBirth":"1987-07-19",
      "emailId":"[email protected]",
      "mobileNo":"6502789426"
   },
   {
      "customerId":"114861",
      "customerName":"Jason Cook",
      "dateOfBirth":"1988-09-22",
      "emailId":"[email protected]",
      "mobileNo":"6002789426"
   },
   ... and so on

]

After getting above response I want to make another HTTP call to fetch details corresponding to customerId which returns me following data(let's say for customerId : 114860) :

[  
   {  
      "offerId":"Offer1",
      "offerName":"Wok_Express",
      "offerUrl":"wok_express.png",
      "offerDescription":"Get 10%  discount. Pizzeria where chefs in striped t-shirts toss handmade pizzas."
   },
   {  
      "offerId":"Offer3",
      "offerName":"Only",
      "offerUrl":"only.png",
      "offerDescription":"Get 15% off on refrigerators, washing machine and LED TVs. Get 10% off on all other gadgets"
   },
   {  
      "offerId":"Offer5",
      "offerName":"MakeMyTrip",
      "offerUrl":"MakeMyTrip.png",
      "offerDescription":"Up to Rs. 3000 cashback* on hotels on MakeMyTrip. Offer valid on a min rate of INR 5000."
   },
   {  
      "offerId":"Offer7",
      "offerName":"High_5_Gifts",
      "offerUrl":"high_5_gifts.png",
      "offerDescription":"Saving 15%* up to Rs 350 on first booking of High 5 Gifts. Visit the nearest store for details"
   }
]

Now I want to merge above two streams so that it will give me following result data :

 [  
   {  
      "customerId":"114860",
      "customerName":"John Dyer",
      "dateOfBirth":"1987-07-19",
      "emailId":"[email protected]",
      "mobileNo":"6502789426",
      "offers":[  
         {  
            "offerId":"Offer1",
            "offerName":"Wok_Express",
            "offerUrl":"wok_express.png",
            "offerDescription":"Get 10%  discount. Pizzeria where chefs in striped t-shirts toss handmade pizzas."
         },
         {  
            "offerId":"Offer3",
            "offerName":"Only",
            "offerUrl":"only.png",
            "offerDescription":"Get 15% off on refrigerators, washing machine and LED TVs. Get 10% off on all other gadgets"
         },
         {  
            "offerId":"Offer5",
            "offerName":"MakeMyTrip",
            "offerUrl":"MakeMyTrip.png",
            "offerDescription":"Up to Rs. 3000 cashback* on hotels on MakeMyTrip. Offer valid on a min rate of INR 5000."
         },
         {  
            "offerId":"Offer7",
            "offerName":"High_5_Gifts",
            "offerUrl":"high_5_gifts.png",
            "offerDescription":"Saving 15%* up to Rs 350 on first booking of High 5 Gifts. Visit the nearest store for details"
         }
      ]
   },
   {  
      "customerId":"114861",
      "customerName":"Jason Cook",
      "dateOfBirth":"1988-09-22",
      "emailId":"[email protected]",
      "mobileNo":"6002789426",
      "offers": [ //array of object of offers for 114861]
   },
   ...and so on
]

To obtain above result set; I used concatMap (tried mergeMap as well) here:

this.commonService.getAllCustomers().pipe(
      concatMap(response => {
        return this.commonService.fetchCustomerOffers(response['customerId']).pipe(
          map(d => {
            response['offers'] = d;
            return response;
          }),
        );
      })
    ).subscribe((res) => {
      console.log(res);

    });

but above code run only once..not for all customerId. Kindly help. I have created stackblitz.

1 Answer 1

2

You can make each element with customerId to be emitted separstely wiyh mergeAll. In that case it will work as you expect

   this.allData = this.commonService.getAllCustomers().pipe(
      mergeAll(),
      concatMap(response => {
        return this.commonService.fetchCustomerOffers(response['customerId']).pipe(
          map(d => {
            response['offers'] = d;
            return response;
          }),
        );
      }),
      scan((x, next) => x.concat([next]), [])
    )

see here

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks this works... Now I want to bind this result data set in HTML using async pipe but HTML is not binding giving error. please see this stackblitz stackblitz.com/edit/…
I removed subscribtion and i believe above function will return observable so binded with async pipe in *ngFor..
In that case we should accumulate all the emitted values in array with scan operator. I will correct my answer and slackblitz
mergeAll and other higher-order observables functions are reviewed also in my video course packtpub.com/web-development/hands-rxjs-web-development-video

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.