Search code examples
javascriptember.jsember-datapromiseember-cli

EmberJS Processing before returning model


How can one do processing on an ember model before returning it in the hook? I currently have something along the following lines in a route

model: function (params) {
        var list_of_modelAs = [];

        this.store.find('modelA').then(function (modelAs) {
            modelAs.forEach ( function (modelA) {
                modelA.get('modelB').then(function(modelB) {
                    if (modelB.get('id') == params.modelB_id) {
                        list_of_modelAs.push(modelA)
                    }
                })
            })
        });

        return list_of_modelAs;
    }

Where modelA and modelB of course are models defined with Ember-Data.

I'm essentially creating an array of models but filtering them first. Really what I want to do is just filter the array of models, but I couldn't figure out another way to do it as modelB is a foreign model (modelA belongsTo modelB, i.e. each modelA has a modelB). Ideally what I'm trying to do is something like:

return this.store.find('modelA', where modelA.modelB.id = someValue)

The problem is, of course, that because of promises and such, only an empty list_of_modelAs is returned and the model comes up empty.

I assume I have to somehow structure this to return a promise from the model hook, but I'm not quite sure how.


Solution

  • return a promise from the model hook

    As I have next to no knowledge of ember, I can only presume that the above is what you are attempting to achieve - this will achieve that

    model: function (params) {
        return this.store.find('modelA') // important you do a return here, to return the promise
        .then(function (modelAs) { // modelAs is an array of modelA - we can use map to change this to an array of modelA.get('modelB') promises
            return Promise.all(modelAs.map(function (modelA) { // Promise.all resolves when the array of promises resolves, it resolves to an array of results
                return modelA.get('modelB').then(function (modelB) { // just do the asynch stuff here, return modelA if the id is OK, otherwise return null which will be filtered out later
                    if (modelB.get('id') == params.modelB_id) {
                        return modelA;
                    }
                    else {
                        return null;
                    }
                });
            }));
        })
        .then(
            function(data) { // data is an array of values returned from Promise.all - filter out the null values as they are the ones that don't have the correct ModelB id
                return data.filter(function(datum) {
                    return datum !== null;
                });
            }
        );
        // the final return value will be a promise of an array of ModelA whose ModelB has the required `id`
    }
    

    called using

    ???.model(params)
    .then(function(modelAs) {
        // NOTE: modelAs is an array of modelA's not promises
    });