简体   繁体   中英

How to pass values from function to an array

Im doing an OpenWeatherMap project with the task of grabbing the temperatures from the API call. I cannot figure out how to pass the temperature values from my 'for' loop to my 'temperature' array that I've defined at the top:

const request = require('request');
let apiKey = 'xxxxxxxxx';
let url = `http://api.openweathermap.org/data/2.5/forecast?lat=30.2240897&lon=-92.0198427000000&units=imperial&${apiKey}`
let temperature = new Array();

request(url, function (err, response, body) {
  if(err){
    console.log('error:', error);
  } else {
    let data = JSON.parse(body);
    let weatherList = data.list;
        for (i=0; i<weatherList.length; i++) {
          temperature[i] = weatherList[i].main.temp;
        }
      return temperature;
  }

});

Any help on how to push the values I've gathered from my for loop to the 'temperature' array would be so helpful!

Since request() is an async call and your further processing depends on the value of temperature array, you need the code to access it, inside that request callback. I'm suspecting you might be immediately accessing the temperature array after the async block of code which is call to request function.

 var arr = new Array(); setTimeout(function(){ arr.push(10); console.log("inside async block"); console.log(arr); }, 1000); console.log("immediately after async block"); console.log(arr); 

The api calls using ajax or fetch whatever method you are using, takes time to return response from server. Since you are making an api call, which is asynchronous and you are trying to assign temperature value before ajax call is finished. That is the reason temperature is always empty. You need to use some callback to access temperature value from inside api response.

Like this:

request(url, function (err, response, body) {
if(err){
    console.log('error:', error);
  } else {
    let data = JSON.parse(body);
    let weatherList = data.list;
        for (i=0; i<weatherList.length; i++) {
          temperature[i] = weatherList[i].main.temp;
        }
      useTemp(temperature);
  }
});

useTemp(temperature)
{
//Do something with temperature
}

I think you have a few things going on here that are holding you back.

First: Request is not a Promise based library, as such we need to wait on the response to return. We need to create a Promise for us to wait for.

Second: ES6 brings us easy ways to make this readable and repeatable.

Below are a few examples of your exact call but done in different methods:

/**
* Must await for a Promise, request does not natively return a Promise, so create one
* */
const request = require('request');
let temperature = new Array();

module.exports.getWeatherRequest = async () => {

// Create Our Returned Promise
function doRequest(url) {
    return new Promise((resolve, reject) => {
        request(url, function (error, res, body) {
            if (error) {
                reject(error)
            }

            resolve(JSON.parse(body));

        })
    })
}

/*
 * Call Our Promise
 **/
let resp = await doRequest(url);

/*
 * For/of Loops through Object for only temps
 * Push each value into temperature
 **/
for (let temps of resp.list) {
        temperature.push(temps.main.temp)
    }

/*
 * Outcome
 */
console.log('Temps : ', temperature)

}

ES6 and with Node-Fetch:

const fetch = require('node-fetch');
module.exports.getWeatherFetch = async () => {

let weather = await fetch(url)
    .then(blob => blob.json())
    .then(data => data)
    .catch(error => { console.error(error) })

console.log('Weather Response ', weather)
// Here you'll handle the data/for of loop
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM