[SalesForce] Using Promises in Lightning components

I'm trying to move a synchronous call in a lightning component to use ES6 promises. I have an API returning an array of JSON objects that is hosted on Heroku and want to call that into a lightning component.

In the component, if I do the following init:

    doInit: function (component, event, helper) {

    var request = new XMLHttpRequest();
    var url = 'https://orgcontroltower.herokuapp.com/getScores';

    request.open('GET', url);
    request.send();

    console.log(request.response);

}

The response returns with the data as expected in the console – after notifications that xhr is deprecated on the main thread etc..

However, if I then try to do the following (first the doInit):

    doInit: function (component, event, helper) {

    console.log('gonna try this callback thingy');


    //grab the data from the API
    helper.getScores().then(
        $A.getCallback(function(result) {
            console.log(result);
        }),
        $A.getCallback(function(error){
            console.log(error);
        })
    );

}

then the helper:

    getScores: function (component, event) {

    return new Promise($A.getCallback(function (resolve, reject) {

        console.log('entered promise function');

        var req = new XMLHttpRequest();
        var controlTowerURL = 'https://orgcontroltower.herokuapp.com';
        //open the request for data
        req.open('GET', controlTowerURL + '/getScores');

        //if resolved
        if (req.status === 200) {

            // Resolve the promise with the response text
            resolve(req.response);
        }
        else {
            // Otherwise reject with the status text
            // which will hopefully be a meaningful error
            reject(Error(req.statusText));
        }

        req.send();

    }));

This throws an error..

Error
at components/c/singleOrg.js:64
at b (aura_prod.js:sourcemap:819)
at Promise (<anonymous>)
at Object.getScores (components/c/singleOrg.js:42)
at doInit (components/c/singleOrg.js:15)
at J.Vc (aura_prod.js:sourcemap:411)
at Object.c [as pb] (aura_prod.js:sourcemap:302)
at pJ (aura_prod.js:sourcemap:400)
at aura_prod.js:sourcemap:401
at $.C.Ua (aura_prod.js:sourcemap:824)

this approach should work – shouldn't it? I can't see where i'm breaking this, but breaking it I am… i'm sure it's to do with event loops somewhere… :S

Best Answer

Broken Promises!! needed to wrap the status in the onload() function! aha! working code below..

({
getScores: function (component, event) {

    return new Promise($A.getCallback(function (resolve, reject) {

        console.log('entered promise function');

        var req = new XMLHttpRequest();
        var controlTowerURL = 'https://orgcontroltower.herokuapp.com';
        //open the request for data
        req.open('GET', controlTowerURL + '/getScores');

        //if resolved
        req.onload = function () {
            if (req.status === 200) {

                console.log('it responsed!');


                // Resolve the promise with the response text
                resolve(req.response);
            }
            else {
                // Otherwise reject with the status text
                // which will hopefully be a meaningful error
                reject(Error(req.statusText));
            }
        };

        req.send();

    }));
}

})

Related Topic