Reputation: 358
I am trying to merge three pieces of data at the backend into one array of objects. I am trying to figure out whether there are sufficient tickets available to proceed with the sale. The three pieces of data are:
A request from the front end to purchase a certain number of a certain type of ticket for an event. This is an array of objects.
The total number of tickets of that type for that event that have already been sold.
The number of tickets of that type that are available to sell from the the Event Document I created in MongoDB.
This is working using the following code. However, it is synchronous and I would like to do it asynchronous to speed up the site.
let numTicketsSought = req.body.numTicketsSought.map(e => { return(
Ticket.find({
userEvent: req.body.userEvent,
ticketTypeID: e.ticketTypeID
}).lean().countDocuments()
.then(number => {
e.ticketsSold = number
return e
}))
})
Promise.all(numTicketsSought).then(numTicketsSoughtdata => {
Event.findById(req.body.userEvent)
.lean()
.then(eventdata => {
numTicketsSoughtdata.map(e => {return (
eventdata.tickets.forEach(f => {
if (e.ticketTypeID === f.ticketTypeID){
e.numberOfTickets = f.numberOfTickets
e.ticketsAvailable = e.numberOfTickets - e.ticketsSold
return e
}
})
)})
})
However, when I try to run Ticket.find and Event.findbyID asynchronously (using Promise.all) the code won't run. Here is the code:
let numTicketsSought = req.body.numTicketsSought.map(e => { return(
Ticket.find({
userEvent: req.body.userEvent,
ticketTypeID: e.ticketTypeID
}).lean().countDocuments()
.then(number => {
e.ticketsSold = number
return e
}))
})
let eventInfo = Event.findById(req.body.userEvent).select('tickets.ticketTypeID tickets.numberOfTickets')
.then().catch(err => console.log(err))
Promise.all([numTicketsSought, eventInfo]).then(data => {
let numTicketsSought = data[0]
let eventInfo = data[1]
console.log('numTicketsSought', numTicketsSought)
console.log('eventInfo', eventInfo)
numTicketsSought.map(e => {return (
eventInfo.tickets.forEach(f => {
console.log('TRIGGERED')
console.log('e.ticketTypeID ', e.ticketTypeID )
console.log('f.ticketTypeID ', f.ticketTypeID )
console.log('----------------')
if (e.ticketTypeID === f.ticketTypeID){
console.log('MATCHED')
e.numberOfTickets = f.numberOfTickets
e.ticketsAvailable = e.numberOfTickets - e.ticketsSold
return e
}
})
)})
})
This is what the terminal is showing:
numTicketsSought [ Promise {
{ ticketType: 'Early Bird',
ticketTypeID: 1,
numTicketsSought: 1,
ticketsSold: 100 } },
Promise {
{ ticketType: 'Early Bird VIP',
ticketTypeID: 2,
numTicketsSought: 2,
ticketsSold: 15 } } ]
eventInfo { _id: 5de147e1ed01a505f1ee0011,
tickets:
[ { ticketTypeID: 1, numberOfTickets: 5 },
{ ticketTypeID: 2, numberOfTickets: 5 },
{ ticketTypeID: 3, numberOfTickets: 10 },
{ ticketTypeID: 4, numberOfTickets: 4 } ] }
TRIGGERED
e.ticketTypeID undefined
f.ticketTypeID 1
----------------
TRIGGERED
e.ticketTypeID undefined
f.ticketTypeID 2
----------------
TRIGGERED
e.ticketTypeID undefined
f.ticketTypeID 3
----------------
TRIGGERED
e.ticketTypeID undefined
f.ticketTypeID 4
----------------
TRIGGERED
e.ticketTypeID undefined
f.ticketTypeID 1
----------------
TRIGGERED
e.ticketTypeID undefined
f.ticketTypeID 2
----------------
TRIGGERED
e.ticketTypeID undefined
f.ticketTypeID 3
----------------
TRIGGERED
e.ticketTypeID undefined
f.ticketTypeID 4
----------------
What am I doing wrong that is prevent Promise.all from using the values from the first Promise?
Upvotes: 1
Views: 775
Reputation: 1216
I think it's because you have an array of Promises
not a single Promise
let numTicketsSought = req.body.numTicketsSought.map(e => { return(
Ticket.find({
userEvent: req.body.userEvent,
ticketTypeID: e.ticketTypeID
}).lean().countDocuments()
.then(number => {
e.ticketsSold = number
return e
}))
})
The problem here is that Array.prototype.map
will return an array.
Promise.All([])
in your case you are doing Promise.all([[],])
You will need to unwrap your promises and concatenate them all together
numTicketsSought.push(eventInfo);
Promise.all(numTicketsSought) // <-- rename numTicketsSought to something better like promisesToComplete
Upvotes: 1