1
votes

I'm going out of my mind trying to figure this one out. When I make an ajax call inside of a model hook where I want (need) to return the results of both the ajax call and data from the store, Ember only wants to return the data from the store and not wait on the results of the ajax call. Here's the code :

model: function() {
        var user = this.modelFor('application').user;
        var org_id = user.get('org').get('id');
        var current_org = this.store.peekRecord('org', org_id);
        var _this = this;
        var redAppsRiskTotal = 0;
        var amberAppsRiskTotal = 0;
        var greenAppsRiskTotal = 0;

        ajax({
            url: _this.modelFor('application').url + '/orgs/' + org_id + '/apps.json?auth_token=' + user.get('auth'),
            type: 'get'
        }).then(function(result) {

            var greenRisk = current_org.get('greenRiskThreshold');
            var redRisk = current_org.get('redRiskThreshold');


            result.forEach(function(app) {

                if (app.total_risk_score < greenRisk) { greenAppsRiskTotal += 1; } else
                if (app.total_risk_score < redRisk) { amberAppsRiskTotal += 1; } else
                { redAppsRiskTotal += 1; }
            });

            console.log(current_org.get('businessLineCount')); // these all display the correct result non-zero results
            console.log(redAppsRiskTotal);
            console.log(amberAppsRiskTotal);
            console.log(greenAppsRiskTotal);
        });

        return { current_org, redAppsTotal: redAppsRiskTotal, // but this only returns the current_org
                                                    amberAppsTotal: amberAppsRiskTotal, // the others are zero
                                                    greenAppsTotal: greenAppsRiskTotal };
    }

I'm totally aware that I'm doing something wrong asynchronously, and it's probably pretty basic, I just can't figure out what. I'm relatively new at Ember. I've tried all sorts of ways -- add a second '.then' to the ajax call, create a function out of the ajax call, call it, then add a '.then' to that, put my return statement inside the .then block, etc etc etc. Nothing works (all of those solutions result in having NO data returned). Please help! Thanks.

2
return statement should contain async call only then model hook will wait for Promise to resolveEmber Freak

2 Answers

1
votes

Basically you just have to return a promise. A good fix for you would to use RSVP.hash:

return Ember.RSVP.hash({ // hash waits for all promises and returns an object with the results.
  ajaxData: ajax(...), // assume that ajax returns a promise
  emberDataObj1: this.store.find(...), // another promise
});
0
votes

model hook will wait for promise to be resolved. you should return Promise or ajax call

import Ember from 'ember';
const { RSVP } = Ember;

export default Ember.Route.extend({
    model: function() {
        var user = this.modelFor('application').user;
        var org_id = user.get('org').get('id');
        var current_org = this.store.peekRecord('org', org_id);        
        var redAppsRiskTotal = 0;
        var amberAppsRiskTotal = 0;
        var greenAppsRiskTotal = 0;        
        return RSVP.resolve($.get(this.modelFor('application').url + '/orgs/' + org_id + '/apps.json?auth_token=' + user.get('auth'))).then((result) => {
            var greenRisk = current_org.get('greenRiskThreshold');
            var redRisk = current_org.get('redRiskThreshold');
            result.forEach(function(app) {
                if (app.total_risk_score < greenRisk) { greenAppsRiskTotal += 1; } 
                else if (app.total_risk_score < redRisk) { amberAppsRiskTotal += 1; } 
                else { redAppsRiskTotal += 1; }
            });            
            return {
                'current_org': current_org,
                'redAppsTotal': redAppsRiskTotal, // but this only returns the current_org
                'amberAppsTotal': amberAppsRiskTotal, // the others are zero
                'greenAppsTotal': greenAppsRiskTotal
            }
        });
    }    
});