Reputation: 769
I've done a mapping before, but not this deeply nested. I am trying to re-populate data from a corrupt db. I have manually reconstructed an orders array. I'm trying to look up data for each player, and then update the fields (which start out null) for each player:
Example: I start with data like this:
const orders = [
{
"paymentID": "ch_456",
"paymentStatus": "PAID",
"user": "[email protected]",
"cart": {
"username": "[email protected]",
"totalQty": 1,
"totalPrice": 80,
"items": [{
"event": "Men's BB",
"division": "Men's",
"level": "BB",
"group": "nonpro",
"field": "PAL",
"day": "Saturday",
"numplayers": 2,
"price": 80,
"players": [{
"avp_id": 1042641,
"first": "King",
"last": "Kong",
"waivers": [],
"completed": true,
"country": "USA",
"signed": false},
{
"avp_id": 1086117,
"first": "Jacob",
"last": "Ladder",
"waivers": [],
"completed": true,
"country": "USA",
"signed": false,
"shirt_size": "N/A"}],
"net": null,
"team": null,
"notes": null,
"paymentNote": null,
"waiversSent": false,
"active": true,
"paymentID": "ch_456",
"users": ["[email protected]"],
"paymentStatus": "PAID", "__v": 4}]},
"__v": 0
},{
"paymentID": "ch_123",
"paymentStatus": "PAID",
"user": "[email protected]",
"cart": {
"username": "[email protected]",
"totalQty": 1,
"totalPrice": 50,
"items": [{
"event": "Junior Boys 16s",
"division": "Junior Boys",
"level": "16s",
"group": "nonpro",
"field": "Main",
"day": "Friday",
"numplayers": 2,
"price": 80,
"players": [{
"avp_id": 1022228,
"first": "Some",
"last": "Kid",
"waivers": [],
"completed": true,
"country": "USA",
"signed": false
}, {
"avp_id": 1020142,
"first": "Justin",
"last": "Kid",
"waivers": [],
"completed": true,
"country": "USA",
"signed": false,
"shirt_size": "N/A"
}
],
"net": null,
"team": null,
"notes": null,
"paymentNote": null,
"waiversSent": false,
"active": true,
"paymentID": "ch_123",
"users": ["[email protected]"],
"paymentStatus": "PAID", "__v": 4
}
]
},
"__v": 0
}];
Here is my code, which I'd like to get the data from an API, and update player info to pass into a function further down:
async getLostData() {
// get the lost orders
console.log('start lost data import');
// this.adminService.GetLostOrders().subscribe(orders => {
// console.log('load each order into system', orders);
orders.forEach(order => {
order.cart.items.map(item => {
const players = item.players.map(async player => {
player = await
this.adminService.adminAVPReg(player.last, player.avp_id)
.toPromise();
console.log("updated player outside subscribe", player);
});
item.players = players;
console.log("item", item);
});
// load order with updated info, create registration, and skip pmt
// this.adminService.LoadLostOrders(order).subscribe(data => {
// console.log(data);
// console.log('finished');
// });
});
console.log("orderlist", orders);
// });}
The data I'm getting logged is interesting. What comes back first from the logger is each item, followed by orderlist, and then the updated player info. Each item shows the players array listed as ZoneAwarePromise. I have no idea how to replace that with the actual data, but I can see it's not being logged in the order I expected.
How can I get the item to return with the updated data?
Upvotes: 0
Views: 71
Reputation: 807
From what I understood you are trying to do, I came up with this,
this.adminService.GetLostOrders().pipe(
mergeMap((orders: any[]) => from(orders).pipe(
mergeMap((order) => from(order.cart.items)),
mergeMap((item) => of(item).pipe(
mergeMap(_ => from(item.players)),
mergeMap(player => this.adminService.adminAVPReg(player.last, player.avp_id).pipe(
map(newPlayer => { player = newPlayer; return player; }))
),
toArray(),
tap(newPlayerArray => item.players = newPlayerArray)
)),
toArray(),
mergeMap(_ => this.adminService.LoadLostOrders(orders))
))
).subscribe();
OP's Edit I implemented what you shared above, and turned it into this:
getLostData() {
// get the lost orders
console.log('start lost data import');
// get manually created orders from lostdata collection
this.adminService.GetLostOrders()
.pipe(
mergeMap((orders: any) => from(orders).pipe(
mergeMap((order: any) => from(order.cart.items)),
mergeMap((item: any) => of(item).pipe(
mergeMap(_ => from(item.players)),
mergeMap((player: any) => this.adminService.adminAVPReg(player.last, player.avp_id).pipe(
map((newPlayer: any) => {
player.avp_id = player.avp_id;
player.signed = player.signed;
player.waivers = player.waivers;
player.country = player.country;
player.completed = true;
player.sandbagger = false;
player.first = newPlayer.first;
player.last = newPlayer.last;
player.email = newPlayer.email;
player.address = newPlayer.address;
player.city = newPlayer.city;
player.state = newPlayer.state;
player.zip = newPlayer.zip;
player.shirt_size = newPlayer.shirt_size;
player.ranking = newPlayer.ranking;
player.overallRanking = newPlayer.overallRanking;
player.notes = player.notes;
player.phone = newPlayer.phone;
player.adult = newPlayer.adult;
return player; }))
),
toArray(),
tap(newPlayerArray => item.players = newPlayerArray)
)),
toArray(),
tap(_ => { this.loadlostOrders(orders);
})
))
)
.subscribe();
}
loadlostOrders(orders) {
orders.forEach(order => {
this.adminService.LoadLostOrders(order).subscribe((data) => {
console.log("success", JSON.stringify(data));
}, (error) => {
console.log("error", JSON.stringify(error));
});
});
}
Upvotes: 1