Illegal Violation Claim (Node.js)

Trying to find a unique identifier in Node.js and MongoDB by creating a while loop that queries MongoDB for existing identifiers until a unique value is found. If the identifier is already in use, the number increases at the end until Mongo returns anything.

Everything works, except for the break; statement break; when a unique identifier 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 code using async if someone 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); } }); 
+8
javascript asynchronous mongodb while-loop
source share
1 answer

Your break statement is not inside the loop body. Instead, it is inside the body of the function, namely the findOne . To make this clearer, it is useful to temporarily use a named function as a 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); } }); 

Now it’s clear that break in the body of the callback function is not inside the loop! I also violated other things because the values ​​of uniqueNumber and newUnique no longer in scope, but this is a different problem. :) It is important to note that the function introduces a “hard” border in your code, which is difficult to understand based solely on the language syntax. This is one of the reasons why this programming callback style can be so complex as to be eligible.

Actually, it’s much harder to do this than your original code attempt would have expected. You will need to pass a success signal through possibly arbitrary callback levels, as you repeatedly call findOne and parse the result (asynchronously).

You can get some help with this using the excellent async library like https://github.com/caolan/async#whilst .

+15
source share

All Articles