0

I'm having trouble getting access to the codeToCheck outside of the functions. console.log(abc + ' holy') is printing undefined holy however the console.log(codeToCheck) is printing a random code as it should

  var abc = codeGenerator();

  function codeGenerator() {
    var randomCode = crypto.randomBytes(3).toString("hex");
    codeChecker(randomCode)
    return
  }

  function codeChecker(codeToCheck) {
    mongoose.model("User").find({ refCode: codeToCheck }, function(err, user) {
      if (err) {
        console.log(err);
      } else {
        if (user.length > 0) {
          codeGenerator()
        } else {
          console.log(codeToCheck)
          return          
        }
      }
    });
  }

console.log(abc + ' holy')
Ryan Soderberg
  • 301
  • 2
  • 12
  • 4
    You aren't returning any value. You just have a `return` statement which has no expression after it and thus returns nothing. And a function that returns "nothing" actually returns `undefined` in JavaScript. – VLAZ Jan 09 '20 at 21:21
  • 1
    Also, on a separate note `codeChecker` will still return nothing even if you have a proper expression after `return`, since *that* `return` is inside the callback you give to `find`, not inside `codeChecker`. I'm not sure but I think `mongoose.find` is asynchronous, so you check out [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – VLAZ Jan 09 '20 at 21:23
  • I removed the `return` from the `codeGenerator` function and changed the `return` in `codeChecker` to `return codeToCheck`. Is that correct? I'm still getting undefined unfortunately – Ryan Soderberg Jan 09 '20 at 21:28

1 Answers1

0

EDIT: This solution is wrong because codeChecker is an async function.

The issue is with your returns. You want codeGenerator to always return a code and codeChecker to return a boolean.

var abc = codeGenerator();

function codeGenerator() {
  let randomCode = randomCode = crypto.randomBytes(3).toString("hex");
  while (codeChecker(randomCode)) {
    // Generate a new randomCode if codeChecker returns true
    randomCode = crypto.randomBytes(3).toString("hex");
  }
  return randomCode;
}

function codeChecker(codeToCheck) {
  mongoose.model("User").find({ refCode: codeToCheck }, function(err, user) {
    if (err) {
      console.log(err);
      throw "Error getting users";
    }
    // Returns true if there is already a user with that code
    return user.length > 0;
  });
}

console.log(abc + ' holy')
DoubleE
  • 83
  • 1
  • 6
  • `// Returns true if there is already a user with that code` well it *does* but...there is nothing to receive that return. So it's discarded and goes nowhere. – VLAZ Jan 09 '20 at 21:36
  • Is there a fix for this that you know @VLAZ – Ryan Soderberg Jan 09 '20 at 21:55
  • @RyanSoderberg [yes](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call). The dupe already linked describes in a lot of detail various solutions for how to handle this. – VLAZ Jan 09 '20 at 21:57
  • The while statement takes the return for the function codeChecker – DoubleE Jan 09 '20 at 22:02
  • @DoubleE It doesn't appear to work please see this example https://repl.it/repls/BoldEllipticalSampler – Ryan Soderberg Jan 09 '20 at 22:03
  • return thing === 4 You just set thing = 4 in functionTwo – DoubleE Jan 09 '20 at 22:05
  • You'll also want to return number at the end of functionOne. Here is the full code: https://repl.it/repls/AgileLastingCosmos – DoubleE Jan 09 '20 at 22:06
  • Nevermind. My solution is wrong for the original question. Since codeChecker is an async function, it is not returning the right function. – DoubleE Jan 09 '20 at 22:09
  • @DoubleE Hmm yeah it breaks here https://repl.it/repls/AntiquePushyParallelalgorithm – Ryan Soderberg Jan 09 '20 at 22:16
  • @DoubleE Thank you though! – Ryan Soderberg Jan 09 '20 at 22:16
  • Well no. This (https://repl.it/repls/AntiquePushyParallelalgorithm) breaks because of your || statement on line 13. That statement evaluates like it had parentheses like so: return ((thing === 4) || (7)). That statement always evaluates to true because 7 evaluates to true. – DoubleE Jan 09 '20 at 22:23
  • The correct way to do what you're trying to do is: https://repl.it/repls/FreeThoseElement – DoubleE Jan 09 '20 at 22:24