Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Neil Ganotisi
Neil Ganotisi
20,975 Points

Primary function proceeds while a vital component is still being generated. How do I make the function wait?

Hey guys, working on a project on Node that kind of uses the beginning code base from the Express Basics course.

I stumbled upon a problem when I a POST request gets made at a certain route.

Desired result: Server makes a request to an Overwatch API endpoint, and returns the response from the API to the route /lookup.

Actual result: Server makes a request to an Overwatch API endpoint, Node proceeds to finish the called function without completing the request, leaving the response 'undefined'.

Here's the app.js file I have, and the console result to go with it.

//Load npm modules
const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');

//Set obj 'app' to express();
const app = express();

app.use(bodyParser.urlencoded({ extended: false}));

app.set('view engine', 'pug');

app.get('/', (req, res, next) => {
    res.render('index');
});

app.post('/lookup', (req, res, next) => {
    const battletag = req.body.battletag;
    console.log("running");
    var stats = lookupStats(battletag);
    console.log("lookupStats() completed. Attempting to render stats.");
    res.render(stats);
});

app.listen(3000, () => {
    console.log('The application is running on localhost:3000!')
});


function apiRequestObj(battletag) {
    var requestObj = {
        uri: "https://owapi.net/api/v3/u/" + battletag + "/blob?platform=pc",
        timeout: 10000,
        headers: {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31'
        }
    }
    return requestObj;
}

function apiRequest(requestObj) {
    request(requestObj, function(err, res, body) {
        if (err) {
            return "Error: " + err;
        } else {
            var result = JSON.parse(body);
            result = result.us.stats.competitive.overall_stats;
            console.log(result);
            return result;
        }
    });
}

function lookupStats(battletag) {
    battletag = battletag.replace('#', '-');
    console.log("Searching Battletag: " + battletag);
    var requestObj = apiRequestObj(battletag);
    var apiResult = apiRequest(requestObj);
    console.log(apiResult);
    return apiResult;
}
The application is running on localhost:3000!
running
Searching Battletag: Unreal-11505
undefined
lookupStats() completed. Attempting to render stats.
TypeError: Path must be a string. Received undefined
    at assertPath (path.js:7:11)
    at extname (path.js:1431:5)
    at new View (/Users/neil/Dropbox/Programming/Web Development/owapi/node_modules/express/lib/view.js:56:14)
    at EventEmitter.render (/Users/neil/Dropbox/Programming/Web Development/owapi/node_modules/express/lib/application.js:570:12)
    at ServerResponse.render (/Users/neil/Dropbox/Programming/Web Development/owapi/node_modules/express/lib/response.js:1008:7)
    at app.post (/Users/neil/Dropbox/Programming/Web Development/owapi/app.js:22:9)
    at Layer.handle [as handle_request] (/Users/neil/Dropbox/Programming/Web Development/owapi/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/neil/Dropbox/Programming/Web Development/owapi/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/Users/neil/Dropbox/Programming/Web Development/owapi/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/neil/Dropbox/Programming/Web Development/owapi/node_modules/express/lib/router/layer.js:95:5)
{ level: 61,
  comprank: 2031,
  games: 116,
  win_rate: 53.21,
  losses: 51,
  rank_image: 'https://d1u1mce87gyfbn.cloudfront.net/game/playerlevelrewards/0x0250000000000928_Border.png',
  wins: 58,
  ties: 7,
  prestige: 1,
  avatar: 'https://d1u1mce87gyfbn.cloudfront.net/game/unlocks/0x02500000000002F7.png',
  tier: 'gold' }

Does anyone have an idea of how I can make Node wait for the response from the API endpoint before proceeding?