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
numberOfHeads
specified 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
randomOrder
array. I have tried to implement this with thesetTimeout()
method but I can't seem to get it to change thekeepCalling
Boolean fromtrue
tofalse
in 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)
}
})