I have a simple hasMany/belongsTo relationship that looks like this
App.Foo = DS.Model.extend({
bar: belongsTo('bar', { async: true})
});
App.Bar = DS.Model.extend({
foos: hasMany('foo', { async: true})
});
I have situations in my route code that fire off a request and when the response comes back I access the related "bar" model as I filter down / etc
this.store.all('foo').clear();
var fooz = self.store.all('foo'); //new code
return this.store.find('foo').then(function(response) {
var filtered = response.filter(function(foo) {
return foo.get('bar').get('name') === 'bazz';
});
//other code that would normally be executed top-down
//including side-effect stuff like this
//self.store.createRecord('foo', someHash);
return fooz; //new code
});
The above doesn't work the first time around as foo.get('bar') is a promise. But this is only a problem the first time through (subsequent $.ajax requests seems to have all the bar objects cached so it's a non issue)
What's strange is that before I even boot the app I've already pulled down all the bar data in the init (shown below). So why does ember-data even need to resolve the promise for "bar" when technically that data should already be in the store locally?
App.initializer({
name: 'bootstrap',
initialize: function() {
App.deferReadiness();
var store = App.__container__.lookup("store:main");
var bars = store.find('bar');
var configurations = store.find('configuration');
Ember.RSVP.all([bars, configurations]).then(results) {
App.advanceReadiness();
});
}
});
Ember Data: A Comprehensive Tutorial for the ember-data Library. Ember Data is a library for robustly managing model data in Ember. js applications. Ember Data provides a more flexible and streamlined development workflow, minimizing code churn in response to what would otherwise be high impact changes.
Ember comes with a data management library called Ember Data to help deal with persistent application data. Ember Data requires you to define the structure of the data you wish to provide to your application by extending DS. Model . import DS from 'ember-data'; export default DS.
Let's separate a few things here
this.store.all('foo').clear();
just breaks the internal all
filter until a foo
record is modified/added/removed forcing the filter to recalculate for the record in the store. I say this to show that clear isn't removing the records from ED's store.
Example (click the button, watch the console, read the fun action code)
http://emberjs.jsbin.com/OxIDiVU/103/edit
That being said it isn't the ajax that's being cached, it's the property/relationship on the record instance that's being cached (and the record).
The proper way to remove the records of a type from the store is store.unloadAll('foo')
I know you're already familiar with promises, so this part may be worthless, but, worth documenting
The async relationships are really cool because they return PromiseObject
/PromiseArray
for belongsTo
/hasMany
. The PromiseObject
/PromiseArray
extend ObjectProxy
/ArrayProxy
(these are the same things that ObjectController
/ArrayController
extend). This essentially gives the PromiseObject
/PromiseArray
the ability to proxy getting/setting of properties to the model underneath. In this case the setting/getting happens on the promise doesn't "work" until the promise has been resolved (it won't crash, just return undefined). *Caveat, methods don't exist on the promise, so you can't call save on the promise and expect it to work.
var foo = this.store.find('foo', 1);
var bar = foo.get('bar'); // PromiseObject
bar.get('name'); // undefined
later, bar has resolved, bar is still the PromiseObject
bar.get('name'); // billy
foo will keep returning the PromiseObject
var bar2 = foo.get('bar'); // PromiseObject
bar2.get('name'); // billy
saving
bar.save(); // Boom no workey
bar.then(function(realBar){
realBar.save(); // workey
});
In your case I have 3 recommendations
var self = this;
var promise = new Ember.RSVP.Promise(function(resolve, reject){
self.store.find('foo').then(function(foos) {
Em.RSVP.all(foos.getEach('bar')).then(function(bars){
var filtered = bars.filterBy('name', 'bazz');
resolve(filtered);
});
});
});
return promise;
http://emberjs.jsbin.com/OxIDiVU/104/edit
A lot of times with async objects/properties that aren't resolved during the model hook (which blocks on promises and wait's until they are resolved) a good trick is to set a placeholder object etc.
var items = [];
controller.set('model', items);
// promise from above
promise.then(function(records){
items.pushObjects(records.toArray()); // toArray may or may not apply
});
http://emberjs.jsbin.com/OxIDiVU/106/edit
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With