I have created a route in my REST API that produces a random food order for the user after they send a request with a bunch of parameters. I have a while loop that loops through potential options and places them into the randomOrder array. The loop will run until there are as many items in the random order as numberOfHeads specified by the user. The issue is that sometimes it is impossible to create an order that has something for all mouths to feed and as a result, the loop will run forever. As a backstop for this, I would like to add two conditions to the while loop
If the amount of items in the random order array matches the
numberOfHeadsspecified by the user then the loop can stop.if it tried to do this for a number of seconds but finds itself looping infinitely, I want the loop to stop and simply serve up what it has managed to place in the
randomOrderarray. I have tried to implement this with thesetTimeout()method but I can't seem to get it to change thekeepCallingBoolean fromtruetofalsein order to stop the loop. I am also not sure if I can feed two conditions into a while loop where if either condition becomes true the loop stops?
// RANDOM ORDER FILTER/GENERATOR
router.get("/randomorder", async (req, res) => {
//USERS CHOSEN CATEGORIES SPH & NOP SENT THROUGH THE REQUEST
const restCats = await req.body.restcategories
const menueCats = await req.body.menuecats
var totalSpend = await req.body.totalspend
const numberOfHeads = await req.body.numberofheads
const spendPerHead = totalSpend / numberOfHeads
console.log(spendPerHead)
let restOptions = await Restaurant.aggregate(
[{
$match: {
categories: {
$in: restCats
}
}
}]
)
let randomRestOption = restOptions[Math.floor(Math.random() * restOptions.length)];
//RESULT OF ALL MENUE ITEMS MATCHING USER CATEGORIES
let menueOptions = []
//FULL RESULT OF BOTH RESTURANTS MATCHING USERS CHOSEN CATEGORIES AND MENUE ITEMS OF THOSE RESTURANTS MATCHING USERS CATEGORIES
// LOOPS THROUGH ALL RESTURANT OPTIONS MENUES AND OUTPUTS MENUE ITEMS MATCHING THE USERS CHOSEN CATEGORIES
randomRestOption.menue.filter(function checkoptions(option) {
for (let x = 0; x < option.categories.length; x++) {
// console.log(option)
if (option.categories[x] === menueCats[0] || option.categories[x] === menueCats[1] || option.categories[x] === menueCats[2] || option.categories[x] === menueCats[3] || option.categories[x] === menueCats[4] || option.categories[x] === menueCats[5] || option.categories[x] === menueCats[6]) {
// FILTERS RESULTS BASED ON TOTAL SPEND PER HEAD CHOSEN BY USER
if (option.price <= spendPerHead) {
menueOptions.push(option)
} else if (spendPerHead === undefined) {
menueOptions.push(option)
}
}
}
})
var keepCalling = true
const myTimeout = setTimeout(reAssign, 3000)
function reAssign() {
keepCalling = false
}
myTimeout
let randomOrder = []
console.log(keepCalling)
while (randomOrder.length < numberOfHeads || keepCalling === true) {
// console.log(keepCalling)
let randomMenueOption = menueOptions[Math.floor(Math.random() * menueOptions.length)];
// console.log(randomMenueOption)
function checkDuplicates() {
let duplicate = ""
let itemName = randomMenueOption.name
// console.log(itemName)
for (let i = 0; i < randomOrder.length; i++) {
if (itemName === randomOrder[i].name) {
duplicate = "duplicate"
}
// console.log("loop running")
}
// console.log(randomOrder)
return duplicate
}
let checkduplicate = checkDuplicates()
if (checkduplicate === "duplicate") {
// console.log("Found Duplicate")
} else {
randomOrder.push(randomMenueOption)
}
randomOrder.length;
// console.log(randomMenueOption)
}
// console.log(spendPerHead)
try {
res.status(201).send({
randomOrder
})
} catch (err) {
console.log(err)
}
})