I cant use variable out of function [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I declared a variable names with an empty array value out of the function, then used it inside the function to assign returned value, then I want to use it outside this function, but outside the function this variable remains empty.
Please explain what I'm doing wrong.
handleUpdateInputBusinessName = (searchText) => {
var names = [];
var displaySuggestions = function(predictions, status) {
if (status !== google.maps.places.PlacesServiceStatus.OK) {
alert(status);
return;
}
predictions.forEach(function(prediction) {
let name = prediction.description;
names.push(name);
});
console.log('names_in:', names); // valid predictions from Google Maps Service
return names;
};
console.log('names_out:', names); // []
var service = new google.maps.places.AutocompleteService();
service.getQueryPredictions({ input: searchText, types: '(cities)'
}, displaySuggestions);

Here's the boiled down version:
a = [];
var b = () => {
a.push(1);
console.log('inside:', a)
};
console.log('outside:', a);
b();
The "outside" console log is running before the displaySuggestions function is called, so the data is not yet populated in the array.

you have to use js anonymous function syntax to increse the scope of names array below is the code.
handleUpdateInputBusinessName = (searchText) => {
var names = [];
var displaySuggestions = (predictions, status) => {
if (status !== google.maps.places.PlacesServiceStatus.OK) {
alert(status);
return;
}
predictions.forEach((prediction) => {
let name = prediction.description;
names.push(name);
});
console.log('names_in:', names); // valid predictions from Google Maps Service
return names;
};
console.log('names_out:', names); // []
var service = new google.maps.places.AutocompleteService();
service.getQueryPredictions({ input: searchText, types: '(cities)'
}, displaySuggestions);
hope this heps.

Related

How do I access variables from a nested arrow function? [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed last year.
I am storing the data from an API call in variables and I would like to use the data in the variables elsewhere in the function. However, when I printout what is in the variables outside of the arrow function, the data has a type of undefined.
The first console.log(coordinates); displays ["08002", "39.916258", "-75.021428"] and the second displays
[
"08002",
"39.916258",
"-75.021428"
]
But when I have console.log(coordinates[1]); outside of the arrow function it says it's undefined.
const getLongLat = function(zip) { //gets long lat from a zip code
zip = document.getElementById("ZipCode").value
let lat = 0;
let long = 0;
let coordinates = [];
if (zip == "") {
zip = "08002"
}
coordinates.push(zip);
const APIkey = "#########";
let base = `http://open.mapquestapi.com/geocoding/v1/address?
key=${APIkey}&location=${zip}`;
console.log("base " + base);
fetch(base)
.then(response => response.json())
.then(data => {
//makes it so that the city is in the us
let i = 0;
while (data.results[0].locations[i].adminArea1 != "US") {
i++
}
lat = String(data.results[0].locations[i].latLng.lat);
long = String(data.results[0].locations[i].latLng.lng);
coordinates.push(lat);
coordinates.push(long);
console.log(coordinates);
})
console.log(coordinates);
return coordinates;
};

How to correctly pass "this" into function?

I struggle passing this into my function as demonstrated below:
console.log('geolocation is ' + this.isGeolocating);
let geocoder = new google.maps.Geocoder;
geocoder.geocode({'location': geolocation}, function(results, status, self = this) {
console.log('geolocation is ' + self.isGeolocating);
if (status === 'OK') {
if (results[0]) {
console.log(results[0]);
self.geolocated = 'success';
} else {
// No results found
self.geolocated = 'error';
}
} else {
console.log('Geocoder failed due to: ' + status);
self.geolocated = 'error';
}
});
this.isGeolocating = false;
this is properly accessible before and after the function, but how can I pass it through? self in my case is undefined as well.
There's typically three approaches. One is to assign this to another variable, conventionally named self or that, before the function; the variable will be captured into the function's closure.
let that = this;
geocoder.geocode(..., function(...) {
that.isGeolocating
});
Another is to explicitly tell the function what this should be, using bind:
geocoder.geocode(..., function(...) {
this.isGeolocating
}.bind(this));
The third one is to use a rocket function, which does not reassign this:
geocoder.geocode(..., (...) => {
this.isGeolocating
});
Try this:
let myBeautifulThis = this;
let geocoder = new google.maps.Geocoder;
geocoder.geocode({'location': geolocation}, function(results, status) {
console.log('geolocation is ' + myBeautifulThis.isGeolocating);
});
You need to either store a reference to this in a variable outside of your function, or use arrow functions.
So either
let self = this;
geocoder.geocode({'location': geolocation}, function(results, status) {
// you existing code here
// use self.isGeolocating
});
of just
geocoder.geocode({'location': geolocation}, (results, status) => {
// using this in here will use the this of the outer scope.
// use this.isGeolocating
});

Value of variable outside $.get call not been set [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I am trying to set the value of a variable from inside a $.get jquery call but it is not working. Below is my code
var uData = [];
$('#tfriends').click(function () {
get_json(function () {
alert(uData);
});
});
function get_json(callback) {
$.get('url', function (data) {
var data = $.map(data.result, function (obj) {
obj.Id = obj.Id || obj.name;
obj.text = obj.text || obj.name;
return obj;
}, "json");
uData = data;
});
}
You are not calling your callback function inside the $.get function. Check the comment below.
var uData = [];
$('#tfriends').click(function () {
get_json(function () {
alert(uData);
});
});
function get_json(callback) {
$.get('url', function (data) {
var data = $.map(data.result, function (obj) {
obj.Id = obj.Id || obj.name;
obj.text = obj.text || obj.name;
return obj;
}, "json");
uData = data;
callback() // this line will actually call your callback function
});
}
Edit
As #FelixKling suggested below, you can pass the data in the callback itself rather than declaring a global variable as so
// var uData = [];
$('#tfriends').click(function () {
get_json(function (returned_data) {
alert(returned_data);
});
});
function get_json(callback) {
$.get('url', function (data) {
var data = $.map(data.result, function (obj) {
obj.Id = obj.Id || obj.name;
obj.text = obj.text || obj.name;
return obj;
}, "json");
//uData = data;
callback(data) // this line will actually call your callback function
});
}
This would (IMHO) be better with Promises, abstracting the retrieval of the resource, from the pre-processing, and then from the subsequent application layer handling:
// resource retrieval
function get_json() {
return $.get('url');
}
// pre processing
function preprocess(data) {
// no need to use `.map` since you're modifying the data in-place
data.result.forEach(function(obj) {
obj.Id = obj.Id || obj.name;
obj.text = obj.text || obj.name;
});
return data.result;
}
// chaining it all together
get_json().then(preprocess).then(callback);
If the pre-process stage is always required then it would be acceptable to incorporate that in get_json:
function get_json() {
return $.get('url').then(preprocess);
}

Store JSON object in a global accessible array [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I'm trying to build a function that stores an array of JS objects in a global scope (I want to access this from an external Prototype function). However, when I try to return the 'build' array, the array is undefined (this is probally because I need a proper callback function).
How can I achieve this in a proper way?
function getMyJson(url){
var request = $.getJSON(url);
var items = [];
request.done(function(response) {
for (var key in response) {
if (response.hasOwnProperty(key)) {
var object = {
name: response[key].name,
id: response[key].id
}
items.push(object);
}
}
});
return items; // This returns 'undefined', probally because the for loop is still running
}
var data = getMyJson('data.json');
console.log(data); // undefined
Thanks in advance
As others have mentioned, callbacks are the way to go.
function getMyJson(url, callback){
var request = $.getJSON(url);
var items = [];
request.done(function(response) {
for (var key in response) {
if (response.hasOwnProperty(key)) {
var object = {
name: response[key].name,
id: response[key].id
}
items.push(object);
}
}
callback(items);
});
}
var data = getMyJson('data.json', function(items){
//items will be defined here.
});

Cannot access variable in Javascript array. Console.log says undefined

I have an object which contains an array that I then pass to another function in order for that function to use. The only thing is, when I go to access these variables, console.log says they are undefined. It's strange as when I log the whole array it ways the values are there but when I go to access the array element specifically, it returns undefined.
Here is my code:
googleMapsFunctions.prototype.calculateDistances = function() {
var that = this;
console.log(that.latLngArray);
var closeClubs = [];
var sortable = [];
var resultsArray = [];
jQuery(this.clubs).each(function(key, club) {
var clubLatLng = new google.maps.LatLng(club.latitude, club.longitude);
var distanceFromLoc = clubLatLng.distanceFrom(that, "", "");
//alert(distanceFromLoc);
//that.clubs[key].distance = distanceFromLoc;
//closeClubs.push(club);
});
closeClubs.sort(function(a, b) {
return a.distance - b.distance;
});
}
googleMapsFunctions.prototype.setLatLng = function() {
var that = this;
this.geocoder.geocode({'address' : this.location}, function(results, status) {
if(status === "OK") {
that.latLngArray.push(parseFloat(results[0].geometry.location.lat()));
that.latLngArray.push(parseFloat(results[0].geometry.location.lng()));
}
});
}
//Client Code
var googleMapsClass = new googleMapsFunctions(JSONItems, searchTerm);
googleMapsClass.setLatLng();
googleMapsClass.calculateDistances();
I am using console.log to print out the array (that.latLngArray) which gives the following:
I then click on the aray brackets and it takes me to the following (which is the correct information).
I just can't seem to access these variables and it says that they are undefined.
Can anyone see what is happening here?
Thanks
Simplest thing to do would be to just move the distance calculation inside the callback:
googleMapsFunctions.prototype.setLatLng = function() {
var that = this;
this.geocoder.geocode({'address' : this.location}, function(results, status) {
if(status === "OK") {
that.latLngArray.push(parseFloat(results[0].geometry.location.lat()));
that.latLngArray.push(parseFloat(results[0].geometry.location.lng()));
// now it's safe to check the distances
that.calculateDistances();
}
});
}

Categories