My geocode.js class is below.
const request= require('postman-request')
async function geocode (address, callback){
const url= `https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(address)}.json?access_token=<myToken>&language=tr&limit=1`
request({url, json:true},(error,{body})=>{
if (error) {
callback('Unable to connect to location services!',undefined)
}else if (body.features.length===0) {
callback('Unable to find the location!',undefined)
} else {
callback(undefined,{
latitude: body.features[0].center[1],
longitude: body.features[0].center[0],
location: body.features[0].place_name
})
}
})
}
module.exports= geocode;
My app.js is below.
"use strict";
const geocode = require('../src/geocode.js');
var addressArray= ["Address1", "Address2", "Address3"];
var encodingAddressArray = [];
function getGeoCode(e){
geocode(e,(error,{latitude,longitude, location}={})=>{
// Here the latitude, longitude and location fields come full
return {
latitude: latitude,
longitude: longitude,
location: location
}
})
}
addressArray.forEach(e => {
// But, when I call the getGeoCode function here, it returns undefined.
encodingAddressArray.push(getGeoCode(e))
});
console.log(encodingAddressArray)
The geocode.js class is called within the app.js class. My aim is to print the response data from the request that I have made with the mapbox Api in geocode.js into an array with the forEach loop in app.js. However, when I want to print the response I called from geocode.js to the array I defined in app.js, the data comes as undefined. What should I do? Thank you.
As mentioned in the comment, the issue is that you are using callbacks. Callbacks are notoriously hard for handling in batch, you could fix this by pushing the address to encodingAddressArray inside the callback, but you wouldn't have an easy way to figure out when all requests were finished.
So one way to fix this is to convert the callback to a Promise inside the getGeoCode function:
"use strict";
const geocode = require('../src/geocode.js');
var addressArray= ["Address1", "Address2", "Address3"];
function getGeoCode(e) {
return new Promise((resolve, reject) => {
geocode(e, (error, {latitude,longitude, location} = {}) => {
// Handle error
if (error) {
reject(error);
return;
}
// All is fine, resolve the promise with results
resolve({
latitude: latitude,
longitude: longitude,
location: location
})
})
}
}
// Now we can map addresses array to an array of promises and then work with results:
Promise.all(addressArray.map(e => getGeoCode(e)))
// Here it is guaranteed that all promises are resolved
.then((encodingAddressArray) => console.log(encodingAddressArray))
As further improvement, consider replacing postman-request library with some more modern, promise based alternative like node-fetch, got, or axios. This way you won't need to wrap the results into promise yourself. Once you switch to promises, you can also simplify the code using async / await.