1

I'm adding objects to an array property of a model, then saving it. When I look at the outgoing request, the property in question is always an empty array.

My custom serializer (extending Ember.RESTSerializer) has this:

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 [{foo:'bar'}];
                // return deserialized;
            }
            else if (type == 'string')
            {
                return deserialized.split(',').map(function(item)
                {
                    return item.trim();
                });
            }
            else
            {
                return [];
            }
        }
    });
App.register("transform:array", DS.ArrayTransform);

As you can see I've tried passing back an arbitrary array with an object in it, but even then the array always comes out as empty. In the app I create the record like this:

  var post = this.store.createRecord('explorePost', {
    title: content.get('title'),
    text: content.get('text'),
    postDate: content.get('postdate'),
    publishDate: content.get('publishDate'),
    published: content.get('published'),
    postType: content.get('postType'),
    link: content.get('link,'),
    projectDownloads: [],
    // projectDownloads: this.model.get('projectDownloads'),
    projectLinks: content.get('projectLinks'),
  });

then add the objects like this:

this.model.get('projectDownloads').forEach(function (_download) {
    console.log('pushing download', _download);
    post.get('projectDownloads').pushObject(_download);
  });

I can confirm that at time of saving, the post object has a projectDownloads array with one object in it. No matter what I do I can't seem to get it to spit out the contents when it saves. It's definitely going into the custom serializer, and detects it as an array, but you can see something else seems to be overriding it.

Can anyone tell me what I'm doing wrong? My model setup is below:

    App.ExplorePost = DS.Model.extend(
    {
        title: DS.attr('string'),
        text: DS.attr('string'),
        link: DS.attr('string'),
        postDate: DS.attr('momentdate'),
      publishDate: DS.attr('momentdate'),
      user: DS.belongsTo('user',{async:true}),
      postType: DS.attr('string'),
        activity: DS.belongsTo('activity',{ inverse: 'explorePost', async:true}),
        comments: DS.hasMany('comment',{ inverse: 'explorePost', async: true }),
        // projectDownloads: DS.hasMany('projectDownload',{ inverse: 'explorePost'}),
        projectDownloads: DS.attr('array'),
        // projectLinks: DS.hasMany('projectLink',{ inverse: 'explorePost'}),
        projectLinks: DS.attr('string'),
        published: DS.attr('boolean', {defaultValue: true}),
      // tags: DS.hasMany('tag')

        sortdate: function()
        {
            var datestr = Ember.isEmpty(this.get('postDate')) ? '' : moment(this.get('postDate')).format('YYYYMMDDHHmm');
            var fn = (datestr + '____________').slice(0, 12);
            return fn;
        }.property('postDate')
    });
Toby Tremayne
  • 135
  • 2
  • 14

2 Answers2

1

There's no built in DS.attr('array') and a naive implementation would probably not know how to serialize ember-data objects found inside. Did you intend to leave that in there? If you swap it back to the relationships you've commented out and change projectDownloads to work with the promise:

this.model.get('projectDownloads').then(function(downloads) {
  downloads.forEach(function(_download){
    post.get('projectDownloads').pushObject(_download);
  });
});

This should work jsut fine. I put together something nearly identical the other day. http://emberjs.jsbin.com/zolani/3/edit?html,css,js,output

Kit Sunde
  • 35,972
  • 25
  • 125
  • 179
  • Actually this is an inherited app, it's using an older version of ember-data and trying to upgrade it breaks everything. When I was using proper relationships and embedded records, I had all kinds of problems when it tried to reload the data from the server (Cannot set readonly property of 'id') etc etc. Short version is I need to get it to submit raw json for this array. – Toby Tremayne Aug 19 '15 at 07:24
  • What I can't understand is why even if I pass back arbitrary data to the serialize method, it doesn't use it. What am I missing about this? – Toby Tremayne Aug 19 '15 at 07:24
  • @TobyTremayne Have you checked if `serialize` is being called? Is the attribute not getting serialized at all or just empty `[]`? Have you opted out of that attribute being serialized in the model serializer? It seems to work fine for other people: http://stackoverflow.com/a/19557708/29347 – Kit Sunde Aug 19 '15 at 07:33
  • That's what's confusing me. I don't have a separate serializer for the model, and I can confirm that the arrayTransform serializer IS being called, yet it still comes out as an empty array. I can't see where it's being adjusted. – Toby Tremayne Aug 19 '15 at 07:37
  • @TobyTremayne What values does `type` have in `serialize`? Is it still empty if you do `return [1,2,3]` at the top of that function? – Kit Sunde Aug 19 '15 at 07:40
  • type comes out as 'array' during normal execution in serialize(). Not sure where you want me to test type if I make serialize return [1,2,3]? – Toby Tremayne Aug 19 '15 at 09:51
  • I've just tried returning that simple array always from the serialize() method in my arraytransform, and the output from save() is still the same! So obviously something's not working right there... – Toby Tremayne Aug 19 '15 at 09:56
  • Embarrassingly, I just realized that somewhere during my debugging I'd managed to inadvertently switch to the response tab instead of the request tab, which is why I wasn't seeing any change. When I look now, it's actually going through, so one of the debugging steps I took before worked, but I just wasn't seeing the result! Thank you for your comments, they helped me work through it till I realised, so I've marked your answer correct :) – Toby Tremayne Aug 19 '15 at 10:12
0

if you array not contain complex object, like array of string, you can use DS.attr(), it will work.

zhenhua
  • 57
  • 5