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 combineLatest
and 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);
});