lightweight
lightweight

Reputation: 3337

setting a promise to an external variable

I have a function that returns a promise (I believe, I'm new to javascript) which I'm trying to set to a variable mxY. I've written my functions like this:

function maxYvalue2() {
    return Rpt_scn_cost_v.find({filter: { where: {scenario_id: $stateParams.id}}}).$promise.then(function(response){
        var maxYvalue = 0
        for (var i=0;i<response.length;i++) {
            var currMaxYvalue = parseFloat(response[i].cur_cost) + parseFloat(response[i].tgt_cost);
            if (currMaxYvalue > maxYvalue) {
                maxYvalue = currMaxYvalue
            };
        }
        console.log("yVal: " + maxYvalue)
        return maxYvalue;
    });
};

var mxY = maxYvalue2().then(function (response) {
    console.log("fnc: ", response);
    return response;
});


console.log(mxY);

and my console shows this, where mxY seems to log a {$$state: Object}:

reports.controller.js:99 d {$$state: Object}
    $$state: Object
        status: 1
        value: 78820.3574413
        __proto__: Object
      __proto__: Object
reports.controller.js:88 yVal: 78820.3574413
reports.controller.js:94 fnc:  78820.3574413

from what I understand so far, the .then in maxYvalue2() is returning a promise, which is why I get back $$state.Object, but what I need to do is "unwrap" the promise when it resolves, is that right or am I completely off here? And then I set it to the variable?

------EDIT---------

I'm trying to get the result of maxYvalue2() to go here...change yDomain: [0, 100000] to yDomain: [0, mxY] in the highlighted area below:

function maxYvalue2() {
    return Rpt_scn_cost_v.find({filter: { where: {scenario_id: $stateParams.id}}}).$promise.then(function(response){
        var maxYvalue = 0
        for (var i=0;i<response.length;i++) {
            var currMaxYvalue = parseFloat(response[i].cur_cost) + parseFloat(response[i].tgt_cost);
            if (currMaxYvalue > maxYvalue) {
                maxYvalue = currMaxYvalue
            };
        }
        console.log("yVal: " + maxYvalue)
        return maxYvalue;
    });
};

var mxY = maxYvalue2().then(function (response) {
    console.log("fnc: ", response);
    return response;
});


console.log(mxY);


    $scope.options_scn_cst = {
            chart: {
                type: 'lineChart',
                height: 450,
                margin : {
                    top: 20,
                    right: 20,
                    bottom: 40,
                    left: 55
                },
                x: function(d){ return d.x; },
                y: function(d){ return d.y; },
                useInteractiveGuideline: true,
                dispatch: {
                    stateChange: function(e){ console.log("stateChange"); },
                    changeState: function(e){ console.log("changeState"); },
                    tooltipShow: function(e){ console.log("tooltipShow"); },
                    tooltipHide: function(e){ console.log("tooltipHide"); }
                },
                xAxis: {
                    axisLabel: '',
                    tickFormat: function(d) { return d3.time.format('%b %y')(new Date(d)); }
                },
                yDomain: [0, 100000], //<======change the 100000 to the var mxY
                yAxis: {
                    axisLabel: '$ / month',
                    tickFormat: function(d){
                        return d3.format('$,.0f')(d);
                    },
                    axisLabelDistance: -10
                },
                callback: function(chart){}
            },
            title: {
                enable: true,
                text: 'Scenario Costs Over Time'
            },
            subtitle: {
                enable: false,
                text: 'Put your Subtitle here.',
                css: {
                    'text-align': 'center',
                    'margin': '10px 13px 0px 7px'
                }
            },
            caption: {
                enable: false,
                html: 'Put your Caption Here.',
                css: {
                    'text-align': 'justify',
                    'margin': '10px 13px 0px 7px'
                }
            }
        };

Upvotes: 1

Views: 2011

Answers (1)

Andrew Eisenberg
Andrew Eisenberg

Reputation: 28757

Once you have a promise, there is no way to synchronously unwrap it. Welcome to the land of asynchronous programming!

You can only retrieve the resolution of a promise inside of a then() clause (or a catch() clause if there is an error).

When you call console.log(mxY); you are accessing the promise itself in the same tick that you have created the promise. The promise has not yet been able to resolve. Since JavaScript is single threaded, you can never access the resolution of a promise, except asynchronously.

So, yes, you must use a then() clause. And thankfully, promises provide a mechanism to chain thens.

You could do this:

maxYvalue2().then(function (response) {
    console.log("fnc: ", response);
    return response;
}).then(function (response) {
    // do something
    return newResponse
}).then(function (newResponse) {
    // do something
    return notherNewResponse
}).then(function (notherNewResponse) {
    // etc
    return notherNotherNewResponse
});

What this is showing is that you can chain your promises and use them to perform some fairly complex asynchronous computation.

Upvotes: 1

Related Questions