Non-promise SparkJS?

Hi Guys,

Whilst I understand promises in JS are great, and maybe I am lacking some JS knowledge but is there a way to use the getVariable function with out a promise? eg. wait for a response before proceeding.

Basically I am trying to have a single function refresh some data on the page, however I would like to run the refresh sequentially, in the code I am using the refresh icon will spin until the refresh is completed but with the promise approach I am unable to tell when all the getVariables are finished.

Currently it looks like


device.getVariable('temp', function(err, data) {
  if (err) {
    console.log('An error occurred while getting attrs:', err);
  } else {
    console.log('Device attr retrieved successfully:', data);
  }
});

But I would like to run it as below

var temp = device.getVariable('temp');
var brightness = device.getVariable('brightness');
refreshComplete();

The code above uses a callback, not a promise, if I’m not mistaken. Using that, you should be able to get the desired effect.
Try something like this(?): (not tested)

var temp;
function updateVariables(){
  refreshStart();
  device.getVariable('temp', function(err, data) {
    if (err) {
      console.log('An error occurred while getting attrs:', err);
      refreshStopError();
    } else {
      console.log('Device attr retrieved successfully:', data);
      temp = data;
      refreshStopSucces();
    }
  });
}

Or, even easier, check this: (Again, not tested)

device.getVariable('temp', refreshComplete());

Under the hood, SparkJS uses the when promises library, which provides a convenience method for resolving promises in parallel. Try something like this:

var tempPr = device.getVariable('temp');
var brightnessPr = device.getVariable('brightness');
when.all([tempPr, brightnessPr])
    .then(function(valsArr) {
        var temp = valsArr[0];
        var brightness = valsArr[1];

        // .. do stuff with temp and brightness values ...
        refreshComplete();
    }).catch(function(err) {
        console.log("Failed to fetch one of the variables!", err);
    });

This will execute the two getVariable() calls in parallel. Then when both of them complete, you can handle the returned values, or deal with any errors.

EDIT: Fixed the parameter passed to the then() handler for the all() promise. It resolves to an array, not two separate arguments.

2 Likes

@Moors7 that works great when you do 1 variable, but doing 8 this wont work :wink:

@dougal thanks that should work perfectly! I will give it a shot and see how it goes

2 Likes

@dougal looks like this isn’t compatible with a browser? when I try to use it in a browser it says it cant find the when variable

[Error] ReferenceError: Can't find variable: when
	updateInfo
	(anonymous function)
	emitAndCallback
	(anonymous function)
	(anonymous function)
	on_end
	on_state_change

The code is available through http://bottlelights.semaja2.net

Ah, I didn’t realize that the when library isn’t being exposed. I see you tried to include it separately, but it looks like cdnjs is just linking to a raw file from the repo, and not pointing to a copy of the library that’s been properly built for the browser.

You could download and build the library yourself. Or you could download the sparkjs library, modify it to expose its internal copy of when, and build your own custom sparkjs.

It’s late, but if you need pointers on that, I could give more details tomorrow.

Thanks for that guidance, I compiled the js locally and changed it to be window.when and it now works a treat :smile:

That’s exactly what I was going to suggest! Glad you got it working! :thumbsup: