EmberFire - Load two models in one route - !SOLVED!


#1

I’m trying to load two models in one route and am not having any luck figuring it out. One route to hold all information to dynamically create a form and the other model is the one in which it will push form submission data to. Here is some of what I have so far:

Router Map

App.Router.map(function() {
    this.route('about');
    this.route('plans');
    this.resource('prices', function() {
        this.resource('price', { path: '/:price_id' });
    });
    this.resource('apply', function() {
        this.resource('getstarted');
        this.resource('addresses');
        this.resource('contacts');
        this.resource('drivers');
        this.resource('equipment');
        this.resource('assign');
    });
});

Route

App.GetstartedRoute = Ember.Route.extend({
    model: function(){
        return Ember.Object.create({
            form: function() {
                return EmberFire.Array.create({
                    ref: new Firebase("https://example.firebaseio.com/apply/getstarted")
                 });
             },
            data: function() {
                return EmberFire.Array.create({
                    ref: new Firebase("https://example2.firebaseio.com/companies/-JAY7n7gXJeVbFCCDJdH/carriers/")
                 });
             },
        });
    }
});

FireBase json at getstarted

{
  "_type" : "object",
  "1" : {
    "type" : "text",
    "placeholder" : "Type it in here...",
    "name" : "carrierName",
    "caption" : "What's the name of your carrier?"
  }
}

The form is created via recursing through the first model, putting the data into a component that generates the form. I’m trying to access data in the first model using something such as:

{{model.form.type}}

But it is not working…

Any ideas?


#2

You should be returning a promise that only resolves when both parts are loaded. I don’t know anything about EmberFire, but assuming that it works asynchronously, try to imagine something like this:

App.GetstartedRoute = Ember.Route.extend({
  model: function() {
    return new Ember.RSVP.Promise(function(resolve) {
      var obj = {};

      getForm(function(form) {
        obj.form = form;
        if (obj.data) {
          resolve(Ember.Object.create(obj));
        }
      });

      getData(function(data) {
        obj.data = data;
        if (obj.form) {
          resolve(Ember.Object.create(obj));
        }
      });
    });
  }
});

EDIT: The code formatting here is just awful. Why doesn’t it scroll horizontally?

EDIT2: After reading a bit about EmberFire, it seems that EmberFire.Array returns a Promise (or Promise-like object). So while data and form are eventually going to contain the values you want, they won’t at the time that the template runs. And because you’re returning a straight Ember.Object instead of a promise, Ember thinks that the value is completely resolved as soon as it gets it.

It also seems that EmberFire provides no direct callback when it’s resolved, so I would say your best bet is to listen to the change event for the content property on each of the arrays. Just be sure to remove the listener when you’re done.


#3

The fix was the following:

return Ember.Object.create({
  form: EmberFire.Array.create({
          ref: new Firebase("https://example.firebaseio.com/apply/getstarted")
        }),
  data: EmberFire.Array.create({
          ref: new Firebase("https://example2.firebaseio.com/companies/-JAY7n7gXJeVbFCCDJdH/carriers/")
        })
 });

and

changing App.GetstartedController = Ember.ArrayController.extend to App.GetstartedController = Ember.ObjectController.extend