Question

I'm building a store locator and loading a custom module via require. The custom module is dependent on Directions & Search module from microsoft. I hate the callback hell and want to pre load the modules return a promise and action on the custom module once everything is loaded.

Using bluebird for Promise spec and I've tried several approaches Promise.method, Promise.promisify, new Promise(function(resolve, reject){Microsoft.Maps.loadModule({callback:resolve})}) I can't seem to get any of them working.

My latest implementation:

function loadSearch() {
            var resolver = Promise.defer();
            Microsoft.Maps.loadModule('Microsoft.Maps.Search', {
                callback: resolver.resolve
            });
            return resolver.promise;
        } /* end loadSearch */ 

        function loadDirections() {
            var resolver = Promise.defer();
            Microsoft.Maps.loadModule('Microsoft.Maps.Directions', {
                callback: resolver.resolve
            });
            return resolver.promise;
        }

Promise.all([loadSearch(), loadDirections()], function() {
        //do something
    });

results in Uncaught TypeError: Cannot read property '_tryFollow' of undefined bluebird.js Can anyone point out what an obvious error in the latest code or a psuedo code example of loading modules in a promise fashion.

Was it helpful?

Solution

Two things, first of all, Promise.all in Bluebird does not accept a second argument like that, it returns a promise, try :

Promise.all([loadSearch(), loadDirections()]).then(function(results) {
    //do something
});

Or better

Promise.all([loadSearch(), loadDirections()]).spread(function(search,dirs) {
    //do something
});

Second of all, the methods of defer are not bound to the defer instance (JS has dynamic this), use the promise constructor instead:

function loadDirections() {
    return new Promise(function(resolve){
        Microsoft.Maps.loadModule('Microsoft.Maps.Directions', {
             callback: resolve // since this is not a method this is not bound
        });
    });
}

And so on. generally, it is better to prefer the promise constructor over the deferred interface in Bluebird.

In total:

function loadSearch() {
    return new Promise(function(resolve){
        Microsoft.Maps.loadModule('Microsoft.Maps.Search', {
            callback: resolve
        });
    });
} 
function loadDirections() {
    return new Promise(function(resolve){
        Microsoft.Maps.loadModule('Microsoft.Maps.Directions', {
            callback: resolve
        });
    });
}
Promise.all([loadDirections(),loadSearch()]).spread(function(dir,search){
     //both done, results here
});

For what it's worth - I've just raised the issue and better error messages will be given in future versions of Bluebird.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top