AngularJS $http running while my other f unction is not finished - javascript

I have an AngularJS function case where my $http runs even before my first function is finished
Here is an example format of my code:
$scope.function = function(){
$scope.functionOne(); // This function declares all the scope variable that I need to produce to throw on my API
$scope.functionTwo(); // This is the function that throws a request to my API via $http.post
}
I need those variables but every variable is just a blank string when it reaches to my backend because $http throws a request before the first function finishes
UPDATE
$scope.functionOne = function(){
var geocoder = new google.maps.Geocoder();
if(geocoder){
// console.log("dean")
// console.log($scope.dealership.address);
// console.log($scope.dealership.suburb)
geocoder.geocode({
'address': $scope.dealership.address + ', ' + $scope.dealership.suburb || "1/53 Township Drive, West Burleigh"
}, function(result, status){
// console.log("armada");
// console.log(status);
if(status == google.maps.GeocoderStatus.OK){
console.log(result);
var center_lat = result[0].geometry.location.lat();
var center_lng = result[0].geometry.location.lng();
var lat = result[0].geometry.location.lat();
var lng = result[0].geometry.location.lng();
$scope.$apply();
}
$scope.map.center.latitude = center_lat;
$scope.map.center.longitude = center_lng;
$scope.map.markers.pop();
$scope.map.markers.push({
latitude: lat,
longitude: lng
});
$scope.dealership.latitude = lat;
$scope.dealership.longitude = lng;
$scope.$apply();
});
}
};
$scope.functionTwo = function(){
$scope.loadingData = true;
// The code below is a factory on a scope variable
$scope.dealership.create().then(function(response){
});
}

Promises is the way to go. Once you are done with functionOne resolve the variables and then return the promise. Once the promise is successfully resolved run the second method.
Hope this helps
Happy Learning
Vatsal

The better option for depending function call is to use CallBack function.
Try to call your second function in the callback function of first function.
EDIT:
The another approach of angular is using Promises
You can refer more about it at https://docs.angularjs.org/api/ng/service/$qenter link description here

Related

Javascript / API Blank Resolved Promise and Non Global Data from Request

I'm trying to set then grab a session storage variable that is returned from an API I'm using. The API is returning the proper values, and these values are accessible within the function which returns the result and its status, but not outside of the request. The request:
var geom;
var latArray = new Array();
var longArray = new Array();
function getLatLong(placeIdent) {
service = new google.maps.places.PlacesService(document.createElement('div'));
request = {placeId: ""+placeIdent+""};
service.getDetails(request, function(result, status) {
if (status !== google.maps.places.PlacesServiceStatus.OK) {
console.log(status);
} else {
writeLatLongData(result);
while(geom != "") {
lat = geom.lat();
latArray.push(lat);
long = geom.lng();
latArray.push(long);
console.log(geom);
console.log(lat);
console.log(long);
timeout();
}
}
}
)
}
function writeLatLongData(result) {
geom = result.geometry.location;
return geom;
}
I know this function is the source of the problem, but if it's any help I'm attempting to access the stored values like so:
function timeoutOne() {
setTimeout(function(){
getGeometry(placeArray);
}, 1000);
}
timeoutOne();
function getGeometry(placeArray) {
for (var j=0; j < nightsArray.length; j++) {
getLatLong(placeArray[j]);
}
}
I'm pretty sure it's an async issue, but I'm not that familiar with Async/await and everything I've tried just returns an empty value when the promise is resolved (perhaps because the data are not accessible outside of the request function, still).
Does anyone have any suggestions?
What if below condition gets true,
status !== google.maps.places.PlacesServiceStatus.OK
your google places api call is getting failed (may be because you are making too much calls per 10 seconds), if this happens nothing will be returned which in turn making function getLatLong return undefined.
Check if at least once this function returning something.

How to take an javascript object out of a database query to access in the rest of the script

To be able to push markers to the map i need to have the returned data outside of the querying function, but I cant get the data out or return it from the query, how can i make it a global variable, or how can I return the object so I can access it in the rest of the script (not just in the success: function), any help would be appreciated
var query = new Parse.Query("business_and_reviews");
var results = new Parse.Object("business_and_reviews");
query.get("pLaARFh2gD", {
success: function(results) {
console.log(results["attributes"]["lat"]);
lat = results["attributes"]["lat"];
lng = results["attributes"]["lng"];
myLatLng2 = (lat + "," + lng);
console.log(myLatLng2);
myLatLng = new google.maps.LatLng(myLatLng2);
},
error: function(object, error) {
}
});
//lat = results.get(["attributes"]["lat"]);
console.log(lat);
}
You can create a global object (if you really want) and reference it directly in the success object.
However, I'd personally use callbacks to handle the data for both success and fail.
You'd end up with something along the lines of:
//success callback
function createMap(data){
var latlong = data["attributes"]["lat"] + ',' + data["attributes"]["lng"]
var map = new google.maps.LatLng(latlong);
}
//fail callback
function failure(reason){
console.log(reason)
}
//initialising function used to call the API
function initMap(){
getLatLong(createMap, failure)
}
//handles api with callbacks supplied
function getLatLong(successCallback, failCallback){
var query = new Parse.Query("business_and_reviews");
var results = new Parse.Object("business_and_reviews");
query.get("pLaARFh2gD", {
success: function(results) {
if(typeof successCallback ==='function') {
successCallback(results)
}
},
error: function(object, error) {
if(typeof successCallback ==='function') {
failCallback(error)
}
}
});
}
//call the function
initMap();

Can't get Googlemaps Geocoder to return LatLng with callback

Can someone look at my code and tell me what I'm doing wrong? I understand that the Googlemaps geocoder is an async function so there needs to be a callback to handle the results. So I'm following the example here but I still can't get it to work:
How do I return a variable from Google Maps JavaScript geocoder callback?
I want to give my codeAddress function an actual address and a callback function. If the results array has something I send the lat and lng to the callback function.
codeAddress = function(address, callback) {
var gpsPosition = {};
if (geocoder) {
geocoder.geocode({'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {
console.log("got results!");
var lat = results[0].geometry.location['B'];
var lng = results[0].geometry.location['k'];
callback(lat, lng);
} else {
alert("No results found");
}
} else {
alert("Geocoder failed due to: " + status);
}
});
}
};
This is the callback function. Basically it takes the lat and lng from the codeAddress function and puts the lat and lng into a hash and returns it. The idea is to then store the hash into a variable called location and reference location when I'm creating a new map marker.
createGPSPosition = function(lat, lng){
console.log("createGPSPosition called with lat and lng:");
console.log(lat);
console.log(lng);
var gpsPosition = {};
gpsPosition.B = lat;
gpsPosition.k = lng;
console.log("gpsPosition:");
console.log(gpsPosition);
return gpsPosition;
};
When I run this code console.log(gpsPosition); actually logs the final hash object. But I still don't see the object getting returned... so when I do:
var stuff = codeAddress("1600 Amphitheatre Pkwy, Mountain View, CA 94043", createGPSPosition)
stuff still turns up as undefined. What's going on here?
This problem is that you're expecting asynchronous code to work in a synchronous way. stuff is defined before codeAddress finishes searching. The simplest solution is to provide a different callback, define stuff within that and use it there. This should work fine:
codeAddress("1600 Amphitheatre Pkwy, Mountain View, CA 94043", function(lat, lng){
var stuff = createGPSPosition(lat, lng);
console.log(stuff); // => your gpsPosition object
});
An alternative would be to learn Promises.

Wait for asynchronous task to complete before continuing?

I'm trying to get location coordinates via the google maps javascript api, which happens asynchronously.
Here is my function for retrieving:
function getCoords(input_address)
{
var geocoder = new google.maps.Geocoder();
var addr = {
address: input_address
};
var callback = function(result, status)
{
if (status == "OK") {
var coords = result[0]['geometry']['location'];
console.log(coords.toUrlValue());
}
};
geocoder.geocode(addr,callback);
}
I want to submit the coordinates along with the rest of a form via an ajax function.
However, testing out the following:
form.submit(function(event){
event.preventDefault();
var addr = $("input[type='text']").val();
getCoords(addr);
console.log('should wait');
});
Outputs:
should wait
coordinates
Is there a way to make sure the getCoords function completes before the next instruction is executed?
Use the callback function for this purpose, do your other job after executed geocoder.geocode(); something like
function getCoords(input_address){
......
......
geocoder.geocode(addr, function (){
doYourJobNow(); //as suggested by tgun926
});
}
function doYourJobNow(){
console.log('should wait');
}
//result would be
//coordinates
//should wait

Returning values in Javascript

I have a (hopefully quite simple) Javascript problem. I've search but found nothing that is really relevant to the problem.
Basically I have a function (addToGlobe) that calls two other functions (codeAddressLat and codeAddressLng) as it runs. The two called functions should both return a float value to the first function, which then uses them. The subfunctions definitely work correctly - I did a print statement to check that the "numfinal" variable in each has a value, and it does.
However, when I add print statements to the calling function (as commented in the code), it returns 'undefined'. Therefore, the problem seems to be when the numfinal value is returned.
Thanks :)
function addToGlobe(uname, uid, pmcity) {
// Get lat & long of city
var pmlat = codeAddressLat(pmcity);
var pmlong = codeAddressLng(pmcity);
log(pmlat); // PROBLEM! Prints 'undefined'
log(pmlong); // PROBLEM! Prints 'undefined'
// Rest of function removed to keep it simple
}
function codeAddressLat(inputcity) {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(-34.397, 150.644);
geocoder.geocode( { 'address': inputcity}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var llsplit = new Array();
bkresult = String(results[0].geometry.location);
bkresult = bkresult.replace(/[\(\)]/g, "");
llsplit = bkresult.split(',');
numfinal = parseFloat(llsplit[0]);
return numfinal;
} else {
log('<b><font color="#C40031">Geocode was not successful:</b> ' + status);
}
});
}
function codeAddressLng(inputcity) {
// Basically the same function as above. Removed for simplicity
}
codeAddressLat is not actually returning anything. The anonymous function it passes to geocoder.geocode is.
Since geocoder.geocode is running asynchronously, codeAddressLat can't wait around for its answer. So codeAddressLat really can't return anything of value. Instead codeAddressLat needs to become asynchronous too. This is a common pattern in JavaScript.
function addToGlobe(uname, uid, pmcity) {
codeAddressLat(pmcity, function(pmlat) {
// do something with pmlat
});
...
}
function codeAddressLat(inputcity, callback) {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(-34.397, 150.644);
geocoder.geocode( { 'address': inputcity}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var llsplit = new Array();
bkresult = String(results[0].geometry.location);
bkresult = bkresult.replace(/[\(\)]/g, "");
llsplit = bkresult.split(',');
numfinal = parseFloat(llsplit[0]);
// instead of returning, call the callback with the result
callback(numfinal);
} else {
log('<b><font color="#C40031">Geocode was not successful:</b> ' + status);
}
});
}
You don't have a return statement in codeAddressLat, you have one inside a callback function defined inside codeAddressLat.
Your function codeAddressLat is not actually returning a value but calling function that you pass a callback function which is returning a value. You need to wait until the geocode operation is complete to retrieve the value of numfinal.
Your function codeAddressLat is not returning any value at all hence you are getting undefined as output.
The geocode request in the codeAddressLat method call and will not return the value to the caller. Your return is of a different scope.
Does this work?
function codeAddressLat(inputcity) {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(-34.397, 150.644);
return geocoder.geocode( { 'address': inputcity}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var llsplit = new Array();
bkresult = String(results[0].geometry.location);
bkresult = bkresult.replace(/[\(\)]/g, "");
llsplit = bkresult.split(',');
numfinal = parseFloat(llsplit[0]);
return numfinal;
} else {
log('<b><font color="#C40031">Geocode was not successful:</b> ' + status);
}
});
}
That geocoder.geocode function looks like it is asynchronous. Your codeAddressLat and codeAddressLng functions returns void before the geocoder.geocode function has got data back from the server.
A way to get around it is to nest your calls to geocoder.geocode and use variable scoping so that when all the AJAX calls have returned you can call your addToGlobe function passing the two parameters you want.
Something like this:
codeAddressLatAndLong(pmcity);
function addToGlobe(pmlatlat, pmlatlong) {
log(pmlat); // PROBLEM! Prints 'undefined'
log(pmlong); // PROBLEM! Prints 'undefined'
// Rest of function removed to keep it simple
}
function codeAddressLatAndLong(inputcity) {
// stuff
geocoder.geocode( { 'address': inputcity}, function(results, status) {
// stuff goes here
pmlat = parseFloat(llsplit[0]);
geocoder.geocode({...}, function(results, status) {
// more stuff
pmlatlong = something;
addToGlobe(pmlatlat, pmlatlong);
});
});
}
Welcome to the world of AJAX.

Categories