2

I am using rollup to build a web bundle for my page. I have one promise chain that is working fine, but another that is attempting to load a map that is not executing.

I've put breakpoints in, and I can see the break at the last line p().then((m)=>console.log) and Q.spread(...), but the other promised methods don't execute.

How am I failing to force the promise to resolve?

Here's my code:

'use strict';

import Q from 'q';
import GoogleMapsApiLoader from 'google-maps-api-loader';

var getPositionIP = function() {
    return new Q( (res,rej) => {
        let oReq = new XMLHttpRequest();
        oReq.onload = function (e) {
            let loc = { coords: e };
            res(loc);
        }
        oReq.open("GET","https://json.geoiplookup.io/");
        oReq.responseType = "json";
        oreq.send();
    });
};

var getPositionGPS = function(options) {
    return new Q( function(resolve, reject) {
        if( navigator.geolocation ) {
            navigator.geolocation.getCurrentPosition(resolve,reject,options);
        } else {
            reject();
        }
    });
};

let mapEngine = GoogleMapsApiLoader({
    libraries: [],
    apiKey: '<<google maps key>>'
});

let positionEngine = function() {
    return getPositionGPS({})
        .catch(() => getPositionIP());
};

let p = function() { 
    return Q.spread(positionEngine, mapEngine).then((pos,map) => {
        var mapcontainer = document.getElementById("map");
        return new map.Map(mapcontainer, {
            center: {lat: pos.coords.latitude, lng: pos.coords.longitude},
            zoom: 8
        }); 
    });
};

p().then((m)=>console.log);
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
PaulProgrammer
  • 16,175
  • 4
  • 39
  • 56
  • 1
    any console errors? – Raz Ronen Jul 12 '20 at 19:36
  • Good question - nothing on the console – PaulProgrammer Jul 12 '20 at 19:56
  • Apparently you're *not* using ES6 promises, but still the Q library? – Bergi Jul 12 '20 at 20:09
  • Still new to this world -- using Q because I thought I heard that ES6 promises weren't uniformly implemented in browsers, and that Q is an implementation of ES6 promises. Also, I need something like `spread()` so that two separate promisfied dependencies can resolve. Bluebird wasn't compiling cleanly, so I tried Q. – PaulProgrammer Jul 12 '20 at 20:11
  • Every modern browser implements ES6 promises just fine. I don't know what compat requirements you have though, internet explorers? Still, you can use polyfills for the missing parts and use standard `Promise` syntax. Using `Q` in your code, and Q-specific methods like `spread`, will just make your code harder to maintain these days. – Bergi Jul 12 '20 at 20:16

1 Answers1

2

That's not how Q.spread would work. A promise still resolves only to a single value, spread is about affecting how the callback will get called. According to the docs, you'll have to write either

return Q.spread([positionEngine, mapEngine], (pos, map) => {

or

return Q.all([positionEngine, mapEngine]).spread((pos, map) => {

The modern approach is to use parameter destructuring syntax though:

return Q.all([positionEngine, mapEngine]).then(([pos, map]) => {

which will also work when you migrate to ES6 promises.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • tried `return Q.all([positionEngine, mapEngine]).then(([pos,map]) => {` but no behavior change. Breakpoint pauses at that line, but none of the promised methods (`getPositionGPS` or the body of the `then` from the `.all()` return) are executed. Still no console errors. – PaulProgrammer Jul 12 '20 at 20:18
  • Removed Q and used Promise directly .. now seeing execution of the `.then()` code ... seeing other issues, but probably not related to the original question. – PaulProgrammer Jul 12 '20 at 20:22
  • Don't forget to slap a `.catch(console.error)` on your final `p().then((m)=>console.log);`. Also notice that your `getPositionIP` does ignore errors from the XHR, see [here](https://stackoverflow.com/questions/30008114/how-do-i-promisify-native-xhr) for how to do it properly – Bergi Jul 12 '20 at 20:22
  • Thanks. Looks like the `getPositionGPS` promise isn't getting called, so there's no way the issue could be `getPositionIP`. – PaulProgrammer Jul 12 '20 at 20:26
  • 1
    Oh, I see, `positionEngine` is a function that you need to call: `Promise.all([positionEngine(), …` – Bergi Jul 12 '20 at 20:28