-3

I have a store that I have added records to, and edited existing records in.

Now I want to sync that data back to the server.

Using store.sync()

This fires off separate requests for each of the sync types (C,R,U,D) (using the proxy api values)

For each sync type, I need to pass a dynamic extraParam (lets make it simple and say extraParam = {type: "Update"} for updates and extraParam = {type: "Add"} for adding), though in application this will be something more complex, like passing a JSON object of user details or params based on the records being synced.

There must be a way to do this, without me having to manually code out a sync function.

Can someone give an example of this if it is possible, or a better approach?

TolMera
  • 452
  • 10
  • 25

2 Answers2

0

Your server proxy takes an api property that contains the various URLs:

api: {
    read:'MyReadEndpoint',
    create:'MyCreateEndpoint',
    update:'MyUpdateEndpoint',
    delete:'MyDeleteEndpoint'
}

As far as I know, you can directly add GET parameters into these urls:

api: {
    read:'MyEndpoint?action=read',
    create:'MyEndpoint?action=create',
    update:'MyEndpoint?action=update',
    delete:'MyEndpoint?action=delete'
}

When bundling the different endpoints, the sync does a string comparison, and since all endpoint definitions are different, each batch is fired separately.

Alexander
  • 19,906
  • 19
  • 75
  • 162
  • Thanks yes I came across the api config while searching for a solution myself, but this is not a good solution (though perhaps very EXT) since overwriting the proxy's api list would effect other calls to the proxy, which with the async nature of ext, could have strange consequences... but thank you. – TolMera Nov 16 '16 at 14:04
  • 1
    It is a solution that does exactly what you told us you want, but good luck finding a better one... I would say your question is not self-explanatory. – Alexander Nov 16 '16 at 14:09
0

This was my final solution

I needed to over ride the existing sync function, and could have done so by loading a new definition into the overrides folder, but instead chose to put this in my store.

The code for that follows:

Ext.define('db_mubin.store', {
extend: 'Ext.data.Store'
,alias: 'store.db_mubin-store'

,require: 'db_mubin.model'
,model: 'db_mubin.model'

,proxy: {
    type:   'ajax'
    ,url:   '/api'
    ,reader: {
        type: 'json'
        ,rootProperty: 'data'
    }
    ,writer: {
        allowSingle: false  
    }
    ,extraParams: {
        calling: 'mubin'
    }
}

,listeners: {
    //add:  function(){this.sync({})},
    //update:   function(){this.sync({})},
    //remove:   function(){this.sync({})}
}

,sync:  function(options) {
    var me = this,
        operations = {},
        toCreate = me.getNewRecords(),
        toUpdate = me.getUpdatedRecords(),
        toDestroy = me.getRemovedRecords(),
        listeners = me.getBatchListeners();

    options = options || {};
    options.params = options.params || {};

    //<debug> 
    if (me.isSyncing) {
        Ext.log.warn('Sync called while a sync operation is in progress. Consider configuring autoSync as false.');
    }
    //</debug> 

    me.needsSync = false;
    me.isSyncing = true;

    if (toCreate.length > 0) {
        options.params.fetch =  'create';
        operations.create = toCreate;
        me.proxy.batch(Ext.apply(options, {
            operations: operations,
            listeners: listeners,
            params: options.params
        }));
        operations = {};
    }

    if (toUpdate.length > 0) {
        options.params.fetch = 'update';
        operations.update = toUpdate;
        me.proxy.batch(Ext.apply(options, {
            operations: operations,
            listeners: listeners,
            params: options.params
        }));
        operations = {};
    }

    if (toDestroy.length > 0) {
        options.params.fetch = 'destroy';
        operations.destroy = toDestroy;
        me.proxy.batch(Ext.apply(options, {
            operations: operations,
            listeners: listeners,
            params: options.params
        }));
        operations = {};
    }
    me.isSyncing = false;

    return me;
}
});

Now I can call sync at any time, and pass in extra details, such as being able to give the API Authentication details, user details, anything that I NEED to send, I can send.

TolMera
  • 452
  • 10
  • 25