Best Practices when not using Ember Data


#1

In the situation when you can’t use Ember Data, what are some best practices and recommendations for building your own jQuery Ajax data layer? It would seem like helpers like LinkTo will only work as described when the exact same object instance is used in the route.

Should one build their own Identity map to ensure that object instances are only created once per object id?

What are some patterns people have used in production to support deep hasMany type relations with query results?


#2

I’m curious to know a bit about why you’re switching away from Ember Data. I agree that Ember Data isn’t yet the right solution for everything, I would just like to know a bit about why it’s not right for you.


#3

Suggest you have a look at source code for discourse itself. For example, here is the ember.js code that is used to represent your post: https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/models/post.js


#4

We don’t use it because we want to use meaningful HTTP errors, and there was no way to handle anything other than 422 (validation failed) with find() when we last looked.


#5

Thanks, I have been following Discourse very closely, but I’m trying to do more than load single records or all records.

My main point of confusion was how to get a record to load a subset of it’s hasMany relationship based on a search query, and still have things like linkTo mark itself active at the right time, and so on. Find query, or using find with a query as it is now, wouldn’t load the records it had previously loaded without the query on the same controller method and returned JSON packet.


#6

For what it’s worth find with query always goes to the server because we have no way of guaranteeing that the client has already fetched all the relevant records. If you want to filter associations on the client is there any reason why you can’t just use one of the built-in array filtering methods?


#7

That’s a good point. We hope to improve this in the future but for now if you need that, Ember Data isn’t a good option.


#8

Hello Peter!

Sorry, yes that’s actually the behaviour I wanted (query goes back to the server each time).

Here’s the thing: the records that I’m dealing with are encrypted on the server, and a search of them is actually done on the server using pre-filtered keywords and associations to the encrypted records. That’s why I need the filter query to be resolved on the server, and a subset of the hasMany returned as if it was the full record set.

Then again, maybe I’m doing it all wrong, but I have no reference points.


#9

At that point why not extend the RESTAdapter’s Ajax method to handle the statuses you need?


#10

Thats exactly the point why I abonded ember-data for now in our project. The problem with find() is not only the missing error-handling part but also the unability to solve a failed find() because the record remains in the “loading” state.


#11

I’d also like to see some best practices when not using Ember Data.

Ember Data lets you pass a promise-like object into your controller, which has state properties like isLoading in addition to the data. The controller can proxy data in the model. I want to do something just like this without using Ember Data and without having all of the state management code inside of my controller.

Is there a way to use Ember.Object and have it behave similarly to Ember Data’s Model?


#12

That depends on what you mean by “similarly”?


#13

Did you read the rest of what I wrote?


#14

You’re going to wind up reimplementing a state-manager (a state-manager by any other layer…) if you’re going to want to keep track of record states. Write that into your Ember.Object.


#15

There is a nice blog post by @eviltrout about Ember without Ember-Data: http://eviltrout.com/2013/03/23/ember-without-data.html.


#16

Thanks for the great link. I have a specific question that isn’t covered.

I’ve got a route that displays a list of things. Inside the route’s setupController, I’m setting my controller’s content to a particular instance of Ember.ArrayProxy that I wrote (I’m using ArrayProxy instead of Object because it needs addArrayObserver). This works great! When the content of the ArrayProxy changes, it’s reflected in the view via my actual view controller. This ArrayProxy seems to be a good place to put my data retrieval code, and expose pagination functions like loadNext.

Here’s where I run into problems. This ArrayProxy also has some custom state information (e.g. isLoading). I want to be able to bind in the template to “isLoading”. I don’t want to have to bind to “content.isLoading”.

What is it that Ember Data returns from App.Post.find? When a controller’s content is set to App.Post.find(), the view template can bind to both content and isLoading. How can I accomplish the same thing without using Ember Data?

Thanks for the great discussions on this forum and for your expertise here.


#18

I realize I’m really really late to the party but here is an example app showing how I build ember apps w/out ember-data using a simple identity map. My customers often don’t use json api, want very custom object graphs (often many diff patterns inside a single app), embedded json POST (to create a tree of objects w/ dependencies), m2m, m2m self referencing relationships and anything else you can think of.

This simple app shows how I create a repository to do the ajax work/ a deserializer to parse the json and create model objects (very light as this is a demo app but you get the idea).

The identity map I use is ember 1/2/2.1 friendly with no deprecation warnings and I’ve been using it in production apps for almost 18 months now. At the core it’s a simple way to share data structures. If you want dirty tracking/etc I’ve got an optional model you could plugin if needed (also been really happy with this for complex dirty tracking scenarios the last year+).