1

I am encountering some problems with my convertKey function, and I suspect it is due to scope issues. Basically, I try to retrieve a record from my mongo database and store it in a count variable, but when I try to return it, I get "undefined". Surprisingly, console.log(nameSearch + count) works, while return nameSearch + count doesn't. Would really appreciate it if someone could help me on this!

var dbUrl = "kidstartnow",
  collections = ["students", "studentsList"];
var db = require("mongojs").connect(dbUrl, collections);

function Student(name, src) {
  this.name = name.toLowerCase();

  //this function does not work
  this.key = convertKey(this.name);

  this.src = src;
  this.pointsTotal = 0;

  //inserts student into database
  var student = {name: this.name, key: this.key, pointsTotal: this.pointsTotal,
    src: this.src
  };
  db.students.insert(student);

  //converts name to a key by stripping white space and adding a number behind and ensures keys are unique
  //concatenates names together to form namesearch, and checks if entry exists in studentsList
  function convertKey(name) {

    var nameSearch = name.replace(/\s/g, ''),
      count = 1;



    db.studentsList.find({name: nameSearch}, function(err, student) {      
      //if nameSearch does not exist in studentsList, create entry and sets count to 1
      if(err || !student.length) {
        db.studentsList.insert({name: nameSearch, count: 1});
        count = 1;
        return nameSearch + count;
      }

      //if entry does exist, increments count by 1
      else {
        db.studentsList.update({name: nameSearch}, {$inc: {count: 1}}, function(err) {
          if(err) {
            console.log("Error incrementing records");
          }

          db.studentsList.find({name: nameSearch}, function(err, student) {
            count = student[0].count;
            //this works
            console.log(nameSearch + count)
            //but this doesn't
            return nameSearch + count;
          });
        });
      }
    });
  };
}

1 Answer 1

1

You're returning from the callback to db.studentsList.find and not from your convertKey function.

If you want the value to be returned from within db.studentsList.find, you'll need to either supply a callback to convertKey or possibly use a Promise library to make convertKey a deferred/future. Otherwise, your function will return immediately while waiting for your nested async functions to complete.

A callback allows you to pass on the result you're looking for (e.g. callback(nameSearch + count))

edit

Whenever I have questions about the return values of functions, I match braces with comments:

function convertKey(name) {

    var nameSearch = name.replace(/\s/g, ''),
      count = 1;

    db.studentsList.find({name: nameSearch}, function(err, student) {      
      //if nameSearch does not exist in studentsList, create entry and sets count to 1
      if(err || !student.length) {
        db.studentsList.insert({name: nameSearch, count: 1});
        count = 1;
        return nameSearch + count;
      } else {
        db.studentsList.update({name: nameSearch}, {$inc: {count: 1}}, function(err) {
          // ...
          db.studentsList.find({name: nameSearch}, function(err, student) {
             // ...
             return nameSearch + count;
          }); // end db.studentsList.find
        }); // end db.studentsList.update
      } // end else
    }); // end db.studentsList.find

    /**
     * Notice, no return value here...
     */
  }; // end convertKey
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for this! Just one quick followup: I tried adding a callback function, and called it as such, but it does not work. Do you know where I am going wrong this.key = convertKey(this.name, function(text) { return text; });
@DanTang I think you need to read up on Continuation-passing style and there's a pretty good article here. Basically, you'll need to contain all logic relying on the text value within that callback function. This is the same idea as what you're doing in the callback passed to db.studentsList.find.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.