Illegal break statement (Node.js)

21,141

Your 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.

Share:
21,141
alyx
Author by

alyx

Updated on July 16, 2022

Comments

  • alyx
    alyx almost 2 years

    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);
                }
            });
    
  • cHao
    cHao almost 11 years
    Async code of some type is going to be an absolute necessity anyway. So. :)