0
votes

we would like to add lazy loading functionality to our ember project, but it looks like ember will always override fields not returned by the response JSON with NULL. First I get a list of users:

GET https://example.com/users

{
  "users": [
    {
      "id":        1,
      "name":      'user1',
      "email":     '[email protected]',
      "images":    [],
      "posts":     []
    },
    {
      "id":        2,
      "name":      'user2',
      "email":     '[email protected]',
      "images":    [],
      "posts":     []
    },
    {
      "id":        3,
      "name":      'user3',
      "email":     '[email protected]',
      "images":    [],
      "posts":     []
    },
  ]
}

This provides a minimal set of user information, with two empty hasMany relations "images" and "posts".

Now, if somebody want to see the users posts or images he would click a button which triggers the lazy loading:

GET https://example.com/userImages/1

{  
  "user": {
    "id":      1,
    "images": [1,2,3,4]
  },
  "images": [
    {
      "id":     1,
      "name":   "image1",
      "path"    "path/to/img1/" 
    },
    {
      "id":     2,
      "name":   "image2",
      "path"    "path/to/img2/" 
    },
    {
      "id":     3,
      "name":   "image3",
      "path"    "path/to/img3/" 
    },
    {
      "id":     4,
      "name":   "image4",
      "path"    "path/to/img4/" 
    }            
  ]
}

To reduce traffic to a minimum, only the newly loaded information is included. After the adapter has deserialzed and pushed the new data to the store, all fields from User1 which are not included in the payload (name, email) are set to NULL in the ember store (tested with store.pushPayload('model', payload)).

Is there a possibility to update only incoming data? Or is there a common best practice to handle such a case?

Thanks in advance for your help

EDIT: One possibility would be to extend the ember-data "_load()" function with the block

for (var key in record._data) {
    var property = record._data[key];
    if( typeof(data[key]) == 'object' && data[key] == null ) {
       data[key] = property;
    }
 }

But this is the worst possible solution I can imagine.

2

2 Answers

1
votes

I think what you want is the store's update method. It's like push (or pushPayload), except that it only updates the data that you give it.

0
votes

Your property returns a promise and that promise returns whatever came back from the server.

foobar: function() {
    return this.store.find('foobar');
}

When the promise resolves, you have two versions of the data, the one already rendered in the client (dataOld) and the one that just returned from the backend (dataNew). To update the client without removing what hasn't change, you have to merge the old and the new. Something along the lines of:

foobar: function() {
    var dataOld = this.get('foobar');

    return this.store.find('foobar').then(function(dataNew) {
      return Ember.$.merge(dataOld, dataNew);
    });
}