1

How do I set an object's properties from an asynchronous function without losing the values? Someone on another SO thread said that anything that has to do with this function should be kept inside the function. However,I want to assign values from it, and assign it to an object. I'm a little new to OOP Js, so this was confusing to me.

I have this function that gets the user's location. This HTML5 function requires a callback to pass a position object into.

function getInfo()
{
    navigator.geolocation.getCurrentPosition(getPos);
}

This is the function that is referenced in getCurrentPosition().

function getPos(position)
{
PositionObj.lat = position.coords.latitude;
PositionObj.lon = position.coords.longitude;
}

PositionObj:

var PositionObj = 
{
lat:null,
lon:null,
returnLat: function()
             {
             return this.lat;
             },
returnLon: function()
             {
             return this.lon;
             }
};

When I try to access PositionObj's properties, I get null, and not the new value that was assigned by the callback. How do I go about doing this? I've tried things like making the callback an object itself, and passing the values to another function that assigns values to the object. Any help would be appreciated!

6
  • 2
    When are you trying to access PositionObj's properties? The whole thing is asynchronous, meaning that you won't see any value in lat or lon until the location is retrieved and getPos assigns it. Thus, something synchronous like getInfo(); console.log(PositionObj.lat); is definitely not going to work. Commented Jun 23, 2013 at 9:28
  • @MattiasBuelens that's what I am confused about. How would I go about doing it instead of the way you said? (that's exactly what I tried haha). Commented Jun 23, 2013 at 9:30
  • Well, that explains a lot. I'll write an answer, hang on. Commented Jun 23, 2013 at 9:31
  • Whatever processing you need to do, you have to do it in getPos method. Commented Jun 23, 2013 at 9:31
  • You already asked that question: stackoverflow.com/q/17251172/218196. Commented Jun 23, 2013 at 11:04

1 Answer 1

2

The most important question is: when are you trying to access PositionObj's properties? Since the whole thing is asynchronous, you won't see any value in lat or lon until the location is retrieved and getPos assigns it. Thus, something synchronous like:

getInfo();
console.log(PositionObj.lat);

is definitely not going to work. getInfo returns immediately and doesn't wait for the location to come in. That's a good thing: the whole idea about asynchronism is that you don't wait (block) until you get your results. Instead, you give a callback to the function and that function makes sure to call it when the results are retrieved later on. In Hollywood style: "don't call me, I call you!"

Thus, anything that relies on the actual position retrieved by getInfo needs to be in the callback. This means that you have to think and code differently: you'll need to break up your synchronous function into smaller functions which are chained up as callbacks.

In your case, you'd put that console.log(PositionObj.lat) (or anything else you want to do with the position) inside (what you called) getPos (you probably want to think of a better name for that function though).

Here's a more complete example which demonstrates the concept better. An online shop may have something like this on its checkout page:

var position = getPosition(); // using geolocation
var closestShop = getClosestShop(position); // using AJAX to a server-side script
alert("The closest shop is " + closestShop);

However, all those synchronous calls would block the script's execution and the page would "freeze". The user would probably think that his browser crashed, and that's not a great user experience.

If all these actions were asynchronous, you'd restructure it so it looks like this:

getPosition(function(position) {
    getClosestShop(position, function(closestShop) {
        alert("The closest shop is " + closestShop);
    });
});

Here, each function accepts a callback function which it calls when the results are in. They all return immediately, allowing the script to continue execution and keep the page responsive. Of course, nothing stops you from starting another asynchronous action from within this callback, effectively chaining them up.

In fact, this last pattern is so popular that a new mechanism was created to make it more manageable: promises. The inner workings are still the same (functions accepting a callback instead of blocking synchronously) but it looks more pleasant. When you make getPosition and getClosestShop return a promise, you could write:

getPosition().then(getClosestShop).then(function(closestShop) {
    alert("The closest shop is " + closestShop);
});
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much, this is great! I'm going to do some more research on callback functions and refer back to your answer. I'm sure it provides sufficient explanation, so I will go ahead and mark it as right.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.