Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ember.js when using ModelFor('') in conjunction with the back button fails to load data

I am using Ember data and The RESTAdapter with an extension for Django.

Here is a JSBin

Here is how our routes are set up:

App.Router.map(function() {

    this.resource('locations');
    this.resource('location', {path:'locations/:location_id'}, function() {

        this.resource('items', function() {
            this.route('create');
        }); 

        this.resource('item', { path:'item/:item_id' }, function() {
            this.route('edit');
        });

    });
});

App.LocationsRoute = Ember.Route.extend({
    model: function () {
        return this.get('store').find('location');
    }
});


App.ItemsRoute = Ember.Route.extend({
  model: function(){
      //Get the model for the selected location and grab its item list.  
      //This will do a call to /locations/1/items
      return this.modelFor('location').get('items'); 
  }     
});

Now this all works fine when we navigate to locations/1/items. The user is presented with a list of items relevant to the location with id 1.

When the user clicks one of these items it brings the url to #/locations/1/item/1 and displays the details of the item with id 1.

Now what doesnt work is this:

When I hit the back button the #/locations/1/items route loads but it does not have its data any more and no REST call to api/locations/1/items occurs. Even though the data displayed just fine when we first navigated to #/locations/1/items.

It is like Ember said "Well we already loaded that data, so we dont need to call the api again" but the data is somehow not being displayed in our template.

If I change the ItemsRoute model to this:

return this.get('store').find('item');

The scenario above works perfectly fine but the data is not based on our location.

Is there something I am missing with using this.modelFor? Or is my route set up incorrect?

Let me know if theres any extra info you need.

Update 1:

Having changed the model function to this I have discovered some new insights:

model: function(){
    //Get the model for the selected location and grab its item list.  
    //This will do a call to /locations/1/items
    var location = this.modelFor('location');
    var items = location.get('items');
    return items;
} 

Upon first load of #/locations/1/items the location variable holds the location model and the items variable holds something which has a 'content' property, 'isFulfilled: true' and some other things.

This correctly works and displays the list of items. When i click on a particular item and got to #/locations/1/items/1 then hit the back button. The breakpoint triggers and location is still correctly populating with the location model.

However the items variable seems to just be a PromiseArray, do I need to somehow wait for the promise to be fulfilled before this model hook returns? I thought Ember already did this automatically? I suppose this means that the route is loading before the promise is fulfilled and thats why there is not data displayed?

Therefore my list is not populated correctly.

like image 614
abarax Avatar asked Jan 24 '14 00:01

abarax


2 Answers

I'm on a phone, so I'll update this a bit later with more, but the problem is your location resource isn't a child of locations. Becaude of that, ember says why waste time fetching that route if it isn't a part of that resource path. It only hits the location route, which I'm betting you don't have a model hook for fetching the single location (at least based on the code above).

like image 186
Kingpin2k Avatar answered Oct 21 '22 13:10

Kingpin2k


Ok, here is the deal. I have fixed the issue but have no idea why it fixed the issue.

Without further ado:

Here is a jsbin example of the exact setup I have. The only difference between the real one and the jsbin is the fact that I am using the RestAdapter instead of the FixtureAdapter. This is not technically true because I am using the ember-django-rest-adapter which extends the REST one.

The issue described in the question does not present itself in the jsbin but the exact setup with the ember-django-rest-adapter does present the issue.

The fix was to break the cyclic relationship between User -> Site -> Items -> User

For example if I comment out the 'locations' relationship in the User model, the back button works.

Or if I comment out the 'owner' relationship to User in the Item model the back button works.

I might ask a separate question to see what the reasoning behind the problem is, although if someone can shed any light in to why this is happening I'll happily accept the answer here.

like image 35
abarax Avatar answered Oct 21 '22 14:10

abarax