Trying to find unique ID in Node.js and MongoDB, by creating a while loop that queries MongoDB for existing IDs, until a unique value is found. If the ID is already in use, a number is incremented on the end until Mongo returns nothing.
Everything is working, except for the break;
statement when a unique ID is found. Node.js returns: SyntaxError: Illegal break statement
The code:
db.collection('landmarks').findOne({'id':uniqueIDer}, function(err, data){
//if ID exists already
if (data.id){
var uniqueNumber = 1;
while (1) {
var uniqueNum_string = uniqueNumber.toString();
var newUnique = data.id + uniqueNum_string;
db.collection('landmarks').findOne({'id':newUnique}, function(err, data){
if (data.id){
uniqueNumber++;
}
else {
saveLandmark(newUnique);
break;
}
});
}
}
else {
saveLandmark(uniqueIDer);
}
});
What am I doing wrong?
EDIT:
Here's the fixed up code using async if anyone needs it :)
db.collection('landmarks').findOne({'id':uniqueIDer}, function(err, data){
if (data){
var uniqueNumber = 1;
var newUnique;
async.forever(function (next) {
var uniqueNum_string = uniqueNumber.toString();
newUnique = data.id + uniqueNum_string;
db.collection('landmarks').findOne({'id':newUnique,'world':worldVal}, function(err, data){
if (data){
console.log('entry found!');
uniqueNumber++;
next();
}
else {
console.log('entry not found!');
next('unique!'); // This is where the looping is stopped
}
});
},
function () {
saveLandmark(newUnique);
});
}
else {
saveLandmark(uniqueIDer);
}
});
Trying to find unique ID in Node.js and MongoDB, by creating a while loop that queries MongoDB for existing IDs, until a unique value is found. If the ID is already in use, a number is incremented on the end until Mongo returns nothing.
Everything is working, except for the break;
statement when a unique ID is found. Node.js returns: SyntaxError: Illegal break statement
The code:
db.collection('landmarks').findOne({'id':uniqueIDer}, function(err, data){
//if ID exists already
if (data.id){
var uniqueNumber = 1;
while (1) {
var uniqueNum_string = uniqueNumber.toString();
var newUnique = data.id + uniqueNum_string;
db.collection('landmarks').findOne({'id':newUnique}, function(err, data){
if (data.id){
uniqueNumber++;
}
else {
saveLandmark(newUnique);
break;
}
});
}
}
else {
saveLandmark(uniqueIDer);
}
});
What am I doing wrong?
EDIT:
Here's the fixed up code using async if anyone needs it :)
db.collection('landmarks').findOne({'id':uniqueIDer}, function(err, data){
if (data){
var uniqueNumber = 1;
var newUnique;
async.forever(function (next) {
var uniqueNum_string = uniqueNumber.toString();
newUnique = data.id + uniqueNum_string;
db.collection('landmarks').findOne({'id':newUnique,'world':worldVal}, function(err, data){
if (data){
console.log('entry found!');
uniqueNumber++;
next();
}
else {
console.log('entry not found!');
next('unique!'); // This is where the looping is stopped
}
});
},
function () {
saveLandmark(newUnique);
});
}
else {
saveLandmark(uniqueIDer);
}
});
Share
Improve this question
edited Sep 18, 2015 at 3:01
lmjohns3
7,5925 gold badges39 silver badges56 bronze badges
asked Aug 2, 2013 at 18:29
alyxalyx
2,7336 gold badges44 silver badges69 bronze badges
6
|
Show 1 more comment
1 Answer
Reset to default 18Your break
statement is not inside the body of a loop. It is, instead, inside the body of a function, namely the findOne
callback. To see this more clearly, it can be helpful to temporarily use a named function as your callback handler:
var cb = function(err, data){
if (data.id){
uniqueNumber++;
}
else {
saveLandmark(newUnique);
break; // not inside a loop!
}
};
db.collection('landmarks').findOne({'id':uniqueIDer}, function(err, data){
//if ID exists already
if (data.id){
var uniqueNumber = 1;
while (1) {
var uniqueNum_string = uniqueNumber.toString();
var newUnique = data.id + uniqueNum_string;
db.collection('landmarks').findOne({'id':newUnique}, cb);
}
}
else {
saveLandmark(uniqueIDer);
}
});
It's pretty clear now that the break
in the callback function body is not inside a loop! I've also made things break in other ways because the uniqueNumber
and newUnique
values are no longer in scope, but that's a different issue. :) The important thing to see here is that a function introduces a "hard" boundary in your code that can be difficult to see based purely on the syntax of the language. This is one of the reasons why this callback style of programming can be so tricky to get right.
In fact, it's much more difficult to do this than your original attempt at the code would imply. You'll need to have a way of passing a success signal up through possibly arbitrary layers of callbacks as you repeatedly call findOne
and analyze the result (asynchronously).
You might get some help with this by using the excellent async
library, for example https://github.com/caolan/async#whilst.
while (1)
with the asynchronous.findOne()
. The latter requires the engine be idle to finish, which the former never lets it be. – Jonathan Lonowski Commented Aug 2, 2013 at 18:34