Why there is no DS.attr('array')?


#1

I understand that array alone might not says much in JS. but still, it’s to useful. also when i create transformer, i still have a trouble with isDirty, which become, unreliable.


#2

I’m guessing that the team behind Ember-data would want you to handle stuff by relations.

If your model is “House” an array containing room sizes should be a hasMany relation of roomSize. It makes for easier handling of data without need of too much custom code. I have found it way better to work with ember-data than against it. Recently having adopted the DS.EmbeddedRecordsMixin - I have found that most of my pain concerning data post/put have dissapeared.

THAT being said, if you really do believe that you need it you can use this mixin to enable DS.attr(“array”):

DS.ArrayTransform = DS.Transform.extend({
    deserialize: function (serialized) {
        return (Ember.typeOf(serialized) == "array")
            ? serialized
            : [];
    },
    serialize: function (deserialized) {
        var type = Ember.typeOf(deserialized);
        if (type == 'array') {
            return deserialized
        } else if (type == 'string') {
            return deserialized.split(',').map(function (item) {
                return jQuery.trim(item);
            });
        } else {
            return [];
        }
    }
});

App.register("transform:array", DS.ArrayTransform);

#3

I’m aware to this transformer and use it. but it’s buggy because the way ember data works:

  • if i’m planning to use isDirty: 1) i will have replace manually the array every time a single cell is changed; 2) if not, Ember Data will not notice there was a change
  • the way Ember Data compare changed values is oldProp !== newProp. which makes life harder when it comes to array. because: array === array and ['a'] !== ['a'] in JS. so technically there is no way except making flag to array and than compare inner values.
  • i understand they prefer using relations, but making another model makes it much more complex and wasteful of resources. i don’t want to make Email model or PhoneNumber model. i just want the model User to have simple way to contain a few emails or phones

#4

I just posted something here, I can imagine this work for Array, but more broadly for almost any complex objects.


#5

i think this solution is too complex and also it’s had for me understand why you would like non linear data structure (or plain objects)


#6

I wrote a little blog post about my experience with using array modeled data with ember data. Hopefully this will help a little!


#7

@robdel12 Thanks for the write up and this is pretty much how I handle it. The problem with this approach however is with updates. If you ever modify the array, the model will does not register the change. And if you do a clone of the array, add/remove element, and then set it back to the model, dirty tracking only semi works, i.e. it registers that the array is new or dirty, but if you ever change the array back to what it was, unless it is the exact same array object as before, even if every element is the same, it still sees it as dirty (this is the problem with mutable data). So bottom line is, without an empty tranform, read works, write isn’t really quite there.

@oriSomething it seems complex probably because of my subpar writing skills. And the reason why use nonlinear data structure is legacy reason. Some of the tag feature in what I am working on are implemented with postgres json column type.

But generally speaking, i think if we could get a solution to this class of problem, then ember data will work for any document based (or similar) backend, because of the nested structure of those database. Again this “class” of problem is figure out how to deal with updates, i.e. how to get ember-data properly register and track changes.

As an example, imagine if i want to build something like linkedin. Things like awards, employments, education, etc. are not long, unbounded lists. With this type of data, certainly we can model it with the traditional relational style. But it would also be great if we model it as nested attributes on the user objects. We already do this in the nosql backends. And with the improvement postgres made recently in json/jsonb, this is even easier. If we can easily write a transform to 1. parse the raw, nested structure into smart ember objects, and 2. wire up the change tracking, it will make ember data so much more usable.