One of the common things people ask about Ember Data is how to find a single record by it’s attribute. This is because the current revision (11) only offers three methods of fetching records
1 2 3
If you want to search for a user by his username, you have two options
Using .find with smart server side
App.User.find(1) works is that it does a request to
/users/1, which is expected to return just one record.
You could modify your server to accept both
id on the
/users/1 path, which would allow to do
There’s an issue with this though. If you load the same user via his
id, you’ll end up with two records stored in the Ember
Which basically means that if you try to retrieve all of the user records, you will end up with that one user twice.
If you want to read more about this, checkout this GitHub issue
Using a findQuery
This might not seem like the right solution at first, since it returns a
DS.ManyArray instead of just one record, but hang on.
DS.ManyArray is a subclass of
DS.RecordArray, which includes a
To understand how
DS.LoadPromise works, we need to understand what
promises are. There’s a great article about
that, so I won’t go into much detail.
Promise is basically an async monad (I guess that doesn’t help, let’s try again).
Promise is something which allows you to return an object which wraps
around a value, even if you don’t have the value yet. For example if
App.User.findQuery, you’ll get back an empty
It doesn’t wait until the AJAX request is finished, it just returns the empty array, which is populated with the data once the request finishes.
This works because Ember uses data bindings and will automagically
update all of the views once the data is loaded. And also because the
router will wait if it’s model has a state
isLoading. That way you
won’t display a page which is half loaded.
Now that we know we’re getting a
DS.ManyArray, we need to figure out a
way to make it represent only the value of it’s first element, because
that’s what we care about.
1 2 3 4 5 6 7
You can see that we are returning the result of the
instantly, but we’re also setting an asynchronous callback which
resolves the promise to the
firstObject once it is loaded.
Another way you could read the
resolve(x) is from now you’re
x. Using this technique will work in all Ember,
because the data bindings will take care of everything. Always remember
that you don’t need to worry about re-rendering your views, just change
the data and Ember will take care of the rest.