ExtJs 6 - change in ajax update requests

932 Views Asked by At

ExtJs does not expect the same response from the server to confirm updating rows than ExtJs 4.

I have a table with a string id:

Ext.define('App.Product', {
    extend: 'Ext.data.Model',
    fields: [
        {name: 'productid', type: 'string'},
        {name: 'ord', , type: 'int'},
        (...)
    ],
    idProperty: 'nrproduit'
})

Upon saving the changes, the ExtJs client sends the modified data to the server:

[{"ord":1,"productid":"SG30301"},{"ord":3,"productid":"SG30100"}]

In ExtJs 4.2, it expected the server to send the full data of the two products back, like this:

{
    "success":true,
    "data":[{
        "nrproduit":"SG30100",
        "ord":3,
        "author":"...",
        "editor":"...",
        (...)
    },{
        "nrproduit":"SG30301",
        "ord":3,
        "author":"...",
        "editor":"...",
        (...)
    }]
}

In ExtJs 6.2, this no longer works. I get the error

Uncaught Error: Duplicate newKey "SG30100" for item with oldKey "SG30301"

Apparently, the client does not take into account the idProperty, but seems to expect the order of the row to be the same in the response as in the request.

Is there a way to force the client to take into account the ids sent back from the server ? Or is it necessary to change the server code ? Is there somewhere documentation on what exactly changed between ExtJs 4.2 and 6.2 in respect to data synchronization between client and server, that go into these details ?

3

There are 3 best solutions below

2
Alexander On BEST ANSWER

ExtJS considers the order because ids can change, e.g. during insert operations (if the id is generated server-side). To allow for that, in the general case, ExtJS expects to receive the results from the server in the same order in which the records were sent.

However, there's more to it. Under certain circumstances, it uses the id, not the order. You can read Operation.doProcess to find how ExtJS does what it does, and possibly override it if you require a different behaviour.

Edit: It uses the id when the model has the property clientIdProperty, else it uses the order. So, it is enough to add it like this:

Ext.define('App.Product', {
    extend: 'Ext.data.Model',
    fields: [
        {name: 'productid', type: 'string'},
        {name: 'ord', , type: 'int'},
        (...)
    ],
    idProperty: 'nrproduit',
    clientIdProperty: 'nrproduit'
})
1
Vineet On

Just adding clientIdProperty on Model definition solved the issue.

Some more info. Same problem has been asked on sencha forum but solution is not mentioned there. Here is the link to that discussion-

https://www.sencha.com/forum/showthread.php?301898-Duplicate-newKey-quot-x-quot-for-item-with-oldKey-quot-xx-quot

0
jgrocha On

Another alternative solution, if you don't want to change the server side code to handle the clientIdProperty property is to disable the batch mode (with batchActions: false) and all your requests are handled one by one.

This is prevent the error "extjs Ext.util.Collection.updateKey(): Duplicate newKey for item with oldKey". With his approach, you will loose some efficiency.

You have to add this to your model:

   ...
   proxy: {
        type: 'direct',
        extraParams: {
            defaultTable: '...',
            defaultSortColumn: '...',
            defaultSordDirection: 'ASC'
        },
        batchActions: false, // avoid clientIdProperty
        api: {        
            read: 'Server.Util.read',
            create: 'Server.Util.create',
            update: 'Server.Util.update',
            destroy: 'Server.Util.destroy'
        },
        reader: {