1

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.

Fozz
  • 167
  • 3
  • 16

1 Answers1

0

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.

Esailija
  • 138,174
  • 23
  • 272
  • 326
Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • @Esailija whoops :D Thanks fore the catch. – Benjamin Gruenbaum Apr 22 '14 at 21:07
  • Bluebird will now provide better error messages in this case https://github.com/petkaantonov/bluebird/commit/d8014cdef319da01a6bd0a076b5ab6f4b39ed3cc – Benjamin Gruenbaum Apr 22 '14 at 22:33
  • Ah missed the '.then()' in api docs, but I'm confused about promise.defer() vs the constructor. The api [docs](https://github.com/petkaantonov/bluebird/blob/master/API.md#callback---function) for `.callback` are an exact example of using deferred as I have and even make a comment about "This is more efficient way of promisification than using `new Promise.`" --- On another note can you explain here or in a pm `Promise.promisify`. I felt like I should be able to do something like `var promiseLM = Promise.promisifyAll(Microsoft.Maps.loadModule)` and used it something like `promiseLM().then()` – Fozz Apr 23 '14 at 04:35
  • Promise.promisify and promisifyAll are for nodebacks - a way of writing callbacks that Microsoft.Maps doesn't do (at leasft from what I can tell here). You can learn more here: http://stackoverflow.com/questions/22519784/how-do-i-convert-an-existing-callback-api-to-promises – Benjamin Gruenbaum Apr 23 '14 at 04:37