syndac syndac - 4 months ago 10
jQuery Question

Having trouble using promises in jQuery/JavaScript. Script doesn't seem to wait

I'm programming a Particle Photon (like an Arduino). I'm trying to call a variable from it and then use that variable to add a .css class to a div.

The problem is that the variable keeps coming back as

undefined


on the initial call. However, if I call it again a couple of seconds later, it works fine.

This is the API call from Particle:

particle.getVariable({ deviceId: 'DEVICE_ID', name: 'temp', auth: token }).then(function(data) {
console.log('Device variable retrieved successfully:', data);
}, function(err) {
console.log('An error occurred while getting attrs:', err);
});


Here is my version of it:

function getVariable(varName) {
particle.getVariable({ deviceId: device_ID, name: varName, auth: accessToken }).then(function(data) {
return data.body.result;
}, function(err) {
console.log('An error occurred while getting variable:', err);
});
}


I'd like to be able to work with this like

$(".class").addClass(getVariable("var")


I'm pretty new to jQuery and Javascript, but I've been doing a ton of reading on callbacks and promises and getting nowhere. Any idea how to accomplish this?

Answer

You have several issues here.

  1. Your getVariable() function needs to return the promise from particle.getVariable(). That will allow the caller of getVariable() to use .then() on the returned result to get the asynchronous result.

  2. Promises do not magically make an asynchronous operation into a synchronous one. So, your getVariable() function is still asynchronous because it relies on the result of particle.getVariable() which is asynchronous. So, you cannot return the result directly. Instead, you should make it return a promise and the caller of that function can use .then() to retrieve the async result.

  3. Since getVariable() will be asynchronous, you will need to use getVariable(...).then(...) to get access to the async result.

Change to this:

function getVariable(varName) {
    return particle.getVariable({
        deviceId: device_ID,
        name: varName,
        auth: accessToken
    }).then(function (data) {
        return data.body.result;    // this becomes the fulfilled value of the promise
    }, function (err) {
        console.log('An error occurred while getting variable:', err);
        throw err;                  // rethrow error so it will propagate
    });
}

getVariable("var").then(function (result) {
    $(".class").addClass(result);
}, function(err) {
    // handle error here
});

For a lot more description of returning asynchronous values, you can see this: How do I return the response from an asynchronous call?

Comments