Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ember-data - store.find('model') always queries the server

Details: ember-data-1.0.0.beta.3 and the default RESTAdapter

I might have misunderstood how the store.find() method works, but, from my understanding, the following code should not query the server if the records I'm asking for are already present in the store:

var IndexRoute = Em.Route.extend({
    model: function() {
       return this.store.find('link');
    },
});

From the emberjs.com documentation for DS.Store.find():

The find method will always return a promise that will be resolved with the record. If the record was already in the store, the promise will be resolved immediately. Otherwise, the store will ask the adapter's find method to find the necessary data.

I have another route with the exact same model hook, but when I visit that route, and even though the data is already in the store, the server gets queried. And if I go back to the Index route, it gets queried again. Shouldn't .find() handle this?

like image 681
Jorge Marques Avatar asked Oct 29 '13 10:10

Jorge Marques


People also ask

What is model in Ember?

In Ember Data, models are objects that represent the underlying data that your application presents to the user. Note that Ember Data models are a different concept than the model method on Routes, although they share the same name.

What is store in Ember JS?

The store contains all of the data for records loaded from the server. It is also responsible for creating instances of Model that wrap the individual data for a record, so that they can be bound to in your Handlebars templates.

What are adapters in Ember?

In Ember Data, an Adapter determines how data is persisted to a backend data store. Things such as the backend host, URL format and headers used to talk to a REST API can all be configured in an adapter. Ember Data's default Adapter has some built-in assumptions about how a REST API should look.


1 Answers

The find method will always return a promise that will be resolved with the record. If the record was already in the store, the promise will be resolved immediately. Otherwise, the store will ask the adapter's find method to find the necessary data.

This just work when finding by id this.store.find('link', 1). Using this.store.find('link') will always perform requests in the server.

You can get the local data using the all method this.store.all('link'). But in some place of your app, you will need to preload that data using the find method. Otherwise all will return nothing.

You can use the following to get the desired behavior:

App.ApplicationRoute = Ember.Route.extend({
    model: function() {
        // preload all data from the server once
        this.store.find('person');
    }
});

App.LinksRoute = Ember.Route.extend({
  model: function() {      
      // get the local data without request the server
      return this.store.all('person');
  }
});

App.OtherRoute = Ember.Route.extend({
  model: function() {
      // get the local data without request the server
      return this.store.all('person');
  }
});

I made a fiddle with this please give a look http://jsfiddle.net/marciojunior/Az2Uc/

That fiddle uses the jquery mockjax, if you see the browser console the MOCK GET: /people is showed just once, this is like a regular xhr request, but it's mocked. Transitioning to people1 and people2 won't perform other requests just get the local data.

like image 179
Marcio Junior Avatar answered Sep 27 '22 21:09

Marcio Junior