title: How to act on an Express response object based on the result of an asynchronous function?
body: <p>I am attempting to create a simple component of an Express app that takes login credentials via uri parameters of a GET request and either serves a user landing page or an error page based on whether the provided credentials match the MySQL credentials.</p>
  
  <p>As I understand it, I need to provide the rendering function to credentialsAreValid() as a callback, provide the hash comparison as a callback from the MySQL query...  unfortunately I'm strugging with the internals of credentialsAreValid().  As it stands, I get "TypeError: Cannot read property 'res' of undefined", which I think is because credentialsAreValid() resolves before readOnlyConnection.query() calls the callback?</p>
  
  <p>Because readOnlyConnection.query() is a function of MySQL, I have no idea how to pass in it the res parameter from credentialsAreValid().  I'm about two weeks into JS/Express, so it's possible I'm approaching the whole task incorrectly.</p>
  
  <p>Bonus points if anyone can tell me why the match returns false despite casting both to String and appearing to be identical.  (MySQL hash is of type BLOB, but it seems to cast okay, and it fails even using the == operator)</p>
  
  <p>Relevant code:</p>
  
  <pre><code>    router.get('/login/:username/:hash', function(req, res, next) {
              console.log(`attempted login with username=${req.params.username} and hash=${req.params.hash}`);
              login.credentialsAreValid(req.params.username, req.params.hash, res, function(res, valid) {
                      if (valid) {
                              console.log("Login Successful").
                              res.render('login', { title: 'success' });
                      }
                      else {
                              console.log("Login Unsuccessful").
                              res.render('login', { title: 'fail' });
                      }
              })
      });
  
  
      credentialsAreValid = function (username, password, res, callback) {
              console.log(`Checking password for user "${username}"`);
              var clientHash = String(createHash(password));
              console.log(`Hashed ${password} to ${clientHash}`);
              var hashesMatch = readOnlyConnection.query(`SELECT passwordHash FROM users WHERE users.username = "${username}";`, function(err, rows, fields) {
                      var serverHash = (rows.length &gt; 0) ? String(rows[0].passwordHash) : "";
                      console.log(`Comparing clientHash ${clientHash} with serverHash ${serverHash} (${clientHash == serverHash})`);
                      return callback(res, clientHash === serverHash);
                      console.log(`This should never display`);
           });
      };
  </code></pre>
  
  <p>Server console output:</p>
  
  <pre><code>attempted login with username=groucho and hash=password
  Checking password for user "groucho"
  Hashed password to password
  Comparing clientHash password with serverHash password (false)
  Login Unsuccessful
  /home/node/alex-practice/node_modules/mysql/lib/protocol/Parser.js:80
                  throw err; // Rethrow non-MySQL errors
                  ^
  
  TypeError: Cannot read property 'res' of undefined
          at /home/node/alex-practice/routes/index.js:43:46
          at Query.&lt;anonymous&gt; (/home/node/alex-practice/login-helper.js:33:16)
          at Query.&lt;anonymous&gt; (/home/node/alex-practice/node_modules/mysql/lib/Connection.js:502:10)
          at Query._callback (/home/node/alex-practice/node_modules/mysql/lib/Connection.js:468:16)
          at Query.Sequence.end (/home/node/alex-practice/node_modules/mysql/lib/protocol/sequences/Sequence.js:83:24)
          at Query._handleFinalResultPacket (/home/node/alex-practice/node_modules/mysql/lib/protocol/sequences/Query.js:139:8)
          at Query.EofPacket (/home/node/alex-practice/node_modules/mysql/lib/protocol/sequences/Query.js:123:8)
          at Protocol._parsePacket (/home/node/alex-practice/node_modules/mysql/lib/protocol/Protocol.js:278:23)
          at Parser.write (/home/node/alex-practice/node_modules/mysql/lib/protocol/Parser.js:76:12)
          at Protocol.write (/home/node/alex-practice/node_modules/mysql/lib/protocol/Protocol.js:38:16)
  [nodemon] app crashed - waiting for file changes before starting...
  </code></pre>