Kasper Tidemann
Kasper Tidemann

Reputation: 488

How to rollback an unsuccessful GET request in ember-data

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.

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

Answers (1)

Ian Lesperance
Ian Lesperance

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

Related Questions