Home > Software engineering >  Merge multiple POST requests based on the same value of each array. (Angular)
Merge multiple POST requests based on the same value of each array. (Angular)

Time:04-29

These are the two outputs

"statusCode": 200,
    "data": [
        {
            "color": {
                "id": "1111",
                "name": null,
                "hex": null,
                "image": "\/img\/.jpg",
                "subColors": [
                    {
                        "id": null,
                        "name": "White",
                        "hex": "#F5F4F8",
                        "image": null,
                        "subColors": []
                    },
                    {
                        "id": null,
                        "name": "Grey",
                        "hex": "#6c6f70",
                        "image": null,
                        "subColors": []
                    }
                ]
            },
            "articleVariants": [
                {
                    "id": "941282",
                    "articleNumber": "1000204445",
                    "size": "68\/74",
                    ]
                },

and

{
    "statusCode": 200,
    "data": [
        {
            "article": 1000204445,
            "ownStock": 3,
            "supplierStock": 18,
            "notice": null,
            "nextAvailability": null,
            "hasMoreOwnStock": false,
            "ownStockText": "3"
        }
    ]
}

I need to merge these two responses based on the same value from articleVariants.articleNumber and the value of article from the second call.

First

getArticleVariantsByColor(masterArticleId: string, colors: object, sizes: object, language: Language): Observable<ApiResponse> {
    let a = {
      colors,
      sizes,
    };
    return this.http.post<ApiResponse>(
      environment.masterServiceUrl   '/variants/service/'   language.isoCode   '/'   masterArticleId, a);

  }

Second

getStock(article: any): Observable<ApiResponse> {
    return this.http.post<ApiResponse>(
      'https://shopapi/stocks/article/', article)
      ;}

And these are the functions that I've written on the component page.

First call

getArticleVariantsByColor() {
    if (this.masterArticle) {
      const subscription: Subscription = this.articleVariantService.getArticleVariantsByColor(
        this.masterArticle.id,
        {},
        {},
        this.language,
      ).subscribe(apiResponse => {
          this.allArticleVariantsByColor = apiResponse.data as ArticleVariantsByColor[];
          this.allArticleVariantsByColor.forEach(variantColor => {
            variantColor.allArticleVariants = variantColor.articleVariants;
          });
          this.articleVariantsByColor = this.allArticleVariantsByColor;
          this.getStock();
        },
      );
      this.subscriptions.push(subscription);
    }
  }

Second call

getStock() {
    const articleNumbers = this.allArticleVariantsByColor.flatMap(v => {return v.articleVariants}).map(v=> {return Number ( v.articleNumber)});
    const subscription: Subscription = this.stockService.getStock(
      articleNumbers,
    ).subscribe(apiResponse => {
        this._stockService = apiResponse.data as StockService[];
        if (this.masterArticle.stocks.article === this.articleNumbers) {
          return this.availableStocks.map(item => item.map(v=>v.article === articleNumbers) );
        }
      },
    );
    this.subscriptions.push(subscription);
  }

This is supposed to flatten the arrays for articleNumbers, the stockServices is supposed to subscribe to these values and compare them with the requested articlenumbers. If they are equal it is supposed to return the values and map them to the request.

Sadly I'm a bit lost here, maybe someone can help me out? How can I merge these request that have the same value and map the new response to the other.

CodePudding user response:

Especially when working in Angular you can (and probably should) make extensive use of ngrx for things like this.

For your specific problem you could use combineLatest. Roughly like the following:

combineLatest(getStock(...), getArticleVariantsByColor(...)).subscribe(
    [stockResult, articleVariantsResult] => {
        /* Now you can merge the results here and do smth with them
           like assigning to a variable of the component */
        const mergedItems = stockResult.data.map(stock => 
            articleVariantsResult.data.find(variant =>
                variant.articleVariants.include(articleVariant => 
                    articleVariant.articleNumber === stock.article
                )
            )
        )
    }
)

I assume my merge code does not exactly do what you need, i just wanted to demonstrate combineLatestand how you can access the api results. Let me know if you had success

CodePudding user response:

Let's divide the solution into 2 steps.

The first step with no Observables, let's just combine responses.

const response1 = {"statusCode": 200,
"data": [
    {
        "color": {
            "id": "1111",
            "name": null,
            "hex": null,
            "image": "\/img\/.jpg",
            "subColors": [
                {
                    "id": null,
                    "name": "White",
                    "hex": "#F5F4F8",
                    "image": null,
                    "subColors": []
                },
                {
                    "id": null,
                    "name": "Grey",
                    "hex": "#6c6f70",
                    "image": null,
                    "subColors": []
                }
            ]
        },
        "articleVariants": [
            {
                "id": "941282",
                "articleNumber": "1000204445",
                "size": "68\/74",
            },
           ]
        }
        ]
        };
const response2 = {
"statusCode": 200,
"data": [
  {
        "article": 1000204445,
        "ownStock": 3,
        "supplierStock": 18,
        "notice": null,
        "nextAvailability": null,
        "hasMoreOwnStock": false,
        "ownStockText": "3"
    }]};

var dataArray1 = response1.data;
var dataArray2 = response2.data;
const mergedResponse = dataArray2.map(d2 => ({...d2, 
...dataArray1.find(d1 => d1.articleVariants.find(av=> av.articleNumber 
=== d2.article))}));
console.log(mergedResponse);

The second step - forkJoin usage to deal with Observables.

const postResponse1 = of(response1);
const postResponse2 = of(response2);


forkJoin({
    response2: postResponse2,
    response1: postResponse1
})
.subscribe(({response2, response1}) => {
   var dataArray1 = response1.data;
   var dataArray2 = response2.data;
   const mergedResponse = dataArray2.map(d2 => ({...d2, 
      ...dataArray1.find(d1 => 
      d1.articleVariants.find(av=> av.articleNumber === d2.article))}));
      console.log(mergedResponse);
});
  • Related