Reputation: 488
Working with ember-data is amazing, it steps up to most of my data handling challenges out of the box. However, there's one issue I've been digging through Google searches trying to find an answer for.
Say I fire off a GET request to the server to find a record, App.Fruit.find('banana');
. If this record doesn't exist, the backend issues back a status code (404) to the client.
Now, at any given time later on, the 'banana' record might be created by somebody else and thus exist in the database on the server.
However, at this point, any further calls to App.Fruit.find('banana');
does not issue a new GET request to the server.
I've tried calling both banana = App.Fruit.find('banana');
and then banana.get('transaction').rollback();
when the 404 is returned from the server.
I've also tried App.store.get('defaultTransaction').rollback();
just to see if that worked.
I've even attempted setting the transaction state to 'deleted' - like so: banana.get('stateManager').goToState('deleted');
- hoping it would make the App.Fruit.find('banana');
issue a new GET request afterwards. Unfortunately, it did not.
My question is: how do I make ember-data issue a GET request again if a previous request didn't return any data (404)?
Upvotes: 0
Views: 368
Reputation: 5139
There appears to be no official way to do this, and that seems to be by design. The store (through which all requests to find
a record are proxied) remembers the ids you give it and skips the server call if that id has already been seen.
In looking at the code, though, there might be a couple tricks for forcing a repeat lookup.
1. Search by ID
The store doesn't remember the queries you use for complex finds. If you tweak your Rails controller's index action to support these searches, you could query repeatedly like so:
fruit = App.Fruit.find({id: 'banana'});
Because it's a search, it will actually return an array—a DS.AdapterPopulatedRecordArray
, to be precise. That means you'll know it worked when fruit.get('length')
is greater than 0
. It also means you'll have to grab the first record off the array to use it:
banana = fruit.objectAtContent(0);
To support this, your Rails controller action will have to look something like this:
def index
if params[:id]
respond_with Fruit.find_all_by_id(params[:id])
else
# ...
end
end
NB: Make sure you return an array, as that's what Ember Data will be expecting.
2. Manual GET, then Sideload
If you can stomach it, you can perform a manual request to the server. If/when the server responds with the record, you can sideload its JSON into the store:
store.load(App.Fruit, json)
This will automatically add the attributes to whatever instance of that record you have in memory.
Upvotes: 2