Variable not defined node.js

I am trying to use Node.js to get a response from an API, I want to clear the API response and use the result.

So, to access the first API, I have the following code.

In order to save and use the result, I believe I need to store the JSON output globally.

However, I cannot figure out how to do this.

Example -

var request = require('request');

request({url: 'https://www.car2go.com/api/v2.1/vehicles?loc=wien&oauth_consumer_key=car2gowebsite&format=json', json: true}, function(err, res, json) {
if (err) {
    throw err;
}
car2go = json.placemarks;
for (i = 0; i < car2go.length; i++) {
    delete car2go[i].address;
    delete car2go[i].charging;
    delete car2go[i].exterior;
    delete car2go[i].interior;
    delete car2go[i].smartPhoneRequired;
    delete car2go[i].vin
    car2go[i].vendor = 'car2go';
    car2go[i].city = 'wien';
    car2go[i].carmake = 'Smart';
    car2go[i].carmodel = 'Fortwo';
}
console.log(car2go);
});

      

This prints the desired output, but I know this is because my variable is defined inside a function.

I want to access a variable outside of a function.

To check if I can do this, I changed the code to -

var request = require('request');

request({url: 'https://www.car2go.com/api/v2.1/vehicles?loc=wien&oauth_consumer_key=car2gowebsite&format=json', json: true}, function(err, res, json) {
if (err) {
    throw err;
}
car2go = json.placemarks;
for (i = 0; i < car2go.length; i++) {
    delete car2go[i].address;
    delete car2go[i].charging;
    delete car2go[i].exterior;
    delete car2go[i].interior;
    delete car2go[i].smartPhoneRequired;
    delete car2go[i].vin
    car2go[i].vendor = 'car2go';
    car2go[i].city = 'wien';
    car2go[i].carmake = 'Smart';
    car2go[i].carmodel = 'Fortwo';
}
});

console.log(car2go);

      

But if I do this I get

ReferenceError: car2go is not defined

      

I am running Node v0.12.2 on Mac OS Yosemite (10.10.3).

I am admittedly very new to Node and I am more familiar with R, Python and PL SQL.

+3


source to share


2 answers


There is no way to get a reference to it outside of the callback function because the string is console.log

run before the callback function is called. The reason you have to pass a callback function to the request API is because the request library needs to call this function when it makes a request. In the meantime, your application is moving around and doing other things (like running that line console.log

) while it waits for the callback to fire.

However, there are several ways to deal with asynchronous code. My favorite way is with promises. I am using a library called bluebird to handle promises.

var request = require('request');
var Promise = require('bluebird');
var requestP = Promise.promisify(request);

      

The call Promise.promisify(request)

returns a new function that does not accept a callback function, but instead returns a promise .



requestP({ url: 'https://www.car2go.com/api/v2.1/vehicles?loc=wien&oauth_consumer_key=car2gowebsite&format=json', json: true })
  .spread(function(res, json) {
    var car2go = json.placemarks;
    for (i = 0; i < car2go.length; i++) {
      delete car2go[i].address;
      delete car2go[i].charging;
      delete car2go[i].exterior;
      delete car2go[i].interior;
      delete car2go[i].smartPhoneRequired;
      delete car2go[i].vin
      car2go[i].vendor = 'car2go';
      car2go[i].city = 'wien';
      car2go[i].carmake = 'Smart';
      car2go[i].carmodel = 'Fortwo';
    }
  })
  .then(function (car2go) {
    console.log(car2go);
  })
  .catch(function (err) {
    console.error(err);
  });

      

Note: .spread

Same .then

as except that the resolved value is an array (this is because the callback passed to the request library takes 2 arguments, which bluebird will translate into an array that it promised to resolve). .spread

will split the array back into multiple arguments passed to the function you are passing .spread

.

Promise.resolve(['hi', 'there']).then(function (result) {
  console.log(result); // "['hi', 'there']"
});

Promise.resolve(['hi', 'there']).spread(function (str1, str2) {
  console.log(str1); // 'hi'
  console.log(str2); // 'there'
});

      

You won't be able to revert this value entirely back to the same context from which you started the asynchronous call, but you can at least write code that looks somewhat synchronous when using promises.

Without promises, you would be forced to call functions from within functions from within functions from functions;)

+1


source


The response is asynchronous. This means the callback function will be called sometime LATER in the future, so yours console.log(car2go)

will be executed before the callback is called.

The only place where you can reliably use a response is inside the callback, or in a function called by the callback. You cannot use it the way you are trying. Using asynchronous responses in Javascript requires programming in asynchronous mode, which means processing results and using IN results only for asynchronous callbacks.



Here's where it console.log()

should be:

var request = require('request');

request({url: 'https://www.car2go.com/api/v2.1/vehicles?loc=wien&oauth_consumer_key=car2gowebsite&format=json', json: true}, function (err, res, json) {
    if (err) {
        throw err;
    }
    car2go = json.placemarks;
    for (i = 0; i < car2go.length; i++) {
        delete car2go[i].address;
        delete car2go[i].charging;
        delete car2go[i].exterior;
        delete car2go[i].interior;
        delete car2go[i].smartPhoneRequired;
        delete car2go[i].vin
        car2go[i].vendor = 'car2go';
        car2go[i].city = 'wien';
        car2go[i].carmake = 'Smart';
        car2go[i].carmodel = 'Fortwo';
    }
    // here is where the result is available
    console.log(car2go);
});

      

0


source







All Articles