PDA

View Full Version : Updating records



BenjaminDC
23 Jun 2013, 8:39 AM
Hi,

adding and removing records works fine. Syncing to the cloud is no problem in this case.
However, when I want to update a record, changes are made locally but when syncing these changes get lost.


Ext.define('KBCH.model.TableRecord', {
extend: 'Ext.data.Model',

config: {
fields: [
{ name: 'rank', type: 'int' },
{ name: 'name', type: 'string' },
{ name: 'played', type: 'int' },
{ name: 'points', type: 'int' },
{ name: 'won', type: 'int' },
{ name: 'lost', type: 'int' },
{ name: 'draw', type: 'int' }
]
}
});


Ext.define('KBCH.store.TableRecords', {
extend: 'Ext.data.Store',
requires: [
'KBCH.model.TableRecord',
'Ext.io.data.Proxy'
],
config: {
model: 'KBCH.model.TableRecord',
storeId: 'tablerecords',
sorters: [
{
property : 'points',
direction: 'DESC'
}
],
proxy: {
type: 'syncstorage',
id: 'tablerecords',
access:'public'
},
autoLoad: true,
autoSync: false
}
});


In my controller the edited record is saved when pushing a save-button. Everything 's fine, I can see the updated values. But when I want to push these changes to the cloud by tapping a button, I only get the values in the cloud and no changes are made.

saveEdit: function () {
var form = this.getRecordForm(),
values = form.getValues(),
record = form.getRecord();
record.setData(values);
record.setDirty(true);
this.getTable().refresh();
this.closeForm();
},
syncStore: function (button) {
button.disable();
Ext.getStore('tablerecords').sync(function () {this.enable() },button);
}

drindal
24 Jun 2013, 11:44 PM
Hi Benjamin,

I've encountered the same problems. Adding new records to the cloud works fine, but when updating existing records, they will only be updated in localstorage and not transported to the cloud.

@at all

First it looks like it would synchronize with the cloud. Even if I do a total refresh of the page (Ctrl - F5), the changed data is present. But if i clear the browser cache and history etc. of chrome and reload the page, the changes are gone.

I've following console output of the update-attempt of a record.



INFO: Ext.io.data.Proxy.sync: Start sync of database: processgrid
DEBUG: Protocol.sync: start
DEBUG: Protocol.sendGetUpdate
DEBUG: Transport Adding listener for service SyncRpcService
DEBUG: Outstanding RPC requests 1
DEBUG: Transport.send {"service":"SyncRpcService","from":"device-6acbc34e-fb98-4f6a-b2a1-835834e44c3f","msg":{"method":"getUpdates","args":[{"dd":{"userId":"4aa465c7-0bec-48b7-bb94-50eaff6beb35","databaseName":"processgrid","generation":"0","version":2},"rd":{"deviceId":"device-6acbc34e-fb98-4f6a-b2a1-835834e44c3f","replicaId":"b28"},"csv":"b1-77114508-81.b2-77122703.b3-77120877.b5-77120001.b10-77617944.b13-77702078.b22-78305522.b25-77730414.b28-78305925"}],"corr-id":8},"sv":"0.7","deviceSid":"56ec67bd-b2e3-471c-849d-0f86fb8242b8","userSid":"10dff012-42bf-4e3b-a60f-95473a91ec42"}
DEBUG: websocket _emit
Object {id: 23, kind: "data", data: Object}
DEBUG: websocket got
Object {id: 23, kind: "ack", data: Object}
DEBUG: websocket got
Object {kind: "data", data: Object}
DEBUG: Transport.receive {"service":"SyncRpcService","sv":"0.7","msg":{"corr-id":8,"result":{"r":"ok","updates":[],"updates_csv":"","required_csv":"b28-0","status":"success"}}}
DEBUG: Outstanding RPC requests 0
DEBUG: Protocol.receiveResponse
Object {r: "ok", updates: Array[0], updates_csv: "", required_csv: "b28-0", status: "success"}
DEBUG: Protocol.sendPutUpdate
Class {v: Object, self: function, superclass: Object, defaultConfig: emptyFn, config: emptyFn…}
INFO: SyncProxy.getUpdates: Get updates from CSV: b1-77114508-81, b2-77122703, b3-77120877, b5-77120001, b10-77617944, b13-77702078, b22-78305522, b25-77730414, b28-0
INFO: SyncProxy.getUpdates: Dominated Replicas:
DEBUG: Transport Adding listener for service SyncRpcService
DEBUG: Outstanding RPC requests 1
DEBUG: Transport.send {"service":"SyncRpcService","from":"device-6acbc34e-fb98-4f6a-b2a1-835834e44c3f","msg":{"method":"putUpdates","args":[{"dd":{"userId":"4aa465c7-0bec-48b7-bb94-50eaff6beb35","databaseName":"processgrid","generation":"0","version":2},"rd":{"deviceId":"device-6acbc34e-fb98-4f6a-b2a1-835834e44c3f","replicaId":"b28"},"csv":"b1-77114508-81.b2-77122703.b3-77120877.b5-77120001.b10-77617944.b13-77702078.b22-78305522.b25-77730414.b28-78305925","updates":"[[\"b2-77121509\",\"changeDate\",1372145925415,\"b28-78305925\"]]"}],"corr-id":9},"sv":"0.7","deviceSid":"56ec67bd-b2e3-471c-849d-0f86fb8242b8","userSid":"10dff012-42bf-4e3b-a60f-95473a91ec42"}
DEBUG: websocket _emit
Object {id: 24, kind: "data", data: Object}
DEBUG: websocket got
Object {id: 24, kind: "ack", data: Object}
DEBUG: websocket got
Object {kind: "data", data: Object}
DEBUG: Transport.receive {"service":"SyncRpcService","sv":"0.7","msg":{"corr-id":9,"result":{"r":"ok","status":"success"}}}
DEBUG: Outstanding RPC requests 0
DEBUG: Protocol.sync: end Object {r: "ok", sent: 1, status: "success"}
INFO: Ext.io.data.Proxy.sync: End sync of database: processgrid

Does INFO: SyncProxy.getUpdates: Dominated Replicas mean something? Like sencha io thinks, it is the same record?

Sencha IO Team, do you have any clue?

Thanks!

BenjaminDC
25 Jun 2013, 11:48 AM
Hi, Drindal

Thank you for your response. I have the same console output, "Dominated Replicas".
I haven't been able to solve the problem. For new i'm just deleting the old record and adding the new one.
I hope to solve this problem later. Hopefully someone can help us further.

simonbrunel
25 Jun 2013, 11:51 AM
Hi,

@Benjamin: a first guess would be that you are not correctly setting data to your model object. You should use the Ext.data.Model.set() method instead of setData(). Then, by using set(), you will not have to explicitly call setDirty(). Please can you try this code into your app and tell me if it fixes update synchronization.



saveEdit: function () {
var form = this.getRecordForm(),
values = form.getValues(),
record = form.getRecord();
record.set(values);
this.getTable().refresh();
this.closeForm();
},


@drindal: are you using the same method to update your record (i.e. setData)?

drindal
25 Jun 2013, 11:52 PM
Hi NiNIX,

i do both things



var store = Ext.getStore('processgrid');
processgrid = Ext.create('WischWeb.model.ProcessGrid');
processgrid.setData(values);
processgrid.set('createDate', new Date());
processgrid.set('user', email);
processgrid.set('name', values.name);
processgrid.set('orgID', values.orgID);

//because sync storage doesn't support nested models, i save the nested data in an array
var array = new Array();
nestedstore.each(function(process) {
array.push(process.getData());
}, this);

processgrid.set('processData', array);

//only add new record, otherwise only sync store
if (isNewGrid)
store.add(process_grid);

store.sync();


when I update records mostly only the content of the array changes, but this should also be recognized as a changed record. Am I right?

I can't always delete the record before inserting, because the syncing process takes a few seconds (a record has quite a number of data). I fear, there will be an inconstistancy then.

simonbrunel
26 Jun 2013, 1:29 AM
Hi drindal,

Is there a particular reason to use setData() in your code? because calling setData() for an update will not properly handle record internal state (i.e. not marked as dirty, "modified" property not updated, etc.). IO only syncs modified fields (based on the use of Ext.data.Model.getChanges()), When using set() instead of setData(), the record will be marked as dirty and a list of modified fields will be determined. According your code, I think that only "user", "createDate" and "processData" are correctly synced?

Also, should "createData" only be set once, at record creation and not at every updates?

Can you try this method to update your data (assuming that processgrid variable has been correctly initialized with the record to update if !isNewGrid):



var store = Ext.getStore('processgrid'),
nested = [];

nestedstore.each(function(process) {
nested.push(process.getData());
});

if (isNewGrid) {
processgrid = Ext.create('WischWeb.model.ProcessGrid', {
createDate: new Date()
});
}

processgrid.beginEdit();
processgrid.set(values);
processgrid.set({
user: email,
processData: nested
});
processgrid.endEdit();

if (isNewGrid) {
store.add(processgrid);
}

store.sync();


Note that beginEdit and endEdit are here only to avoid record notifications to be sent twice. You can find an example of a model update synced with IO here (https://github.com/simonbrunel/jdi/blob/master/application/app/controller/Task.js#L125).

Please tell me if it fixes your issue.

drindal
26 Jun 2013, 1:55 AM
Thanks for your response,

setData() was kind of a leftover ;)

Changing the data, saving and afterwards pressing Ctrl F5, the changed data is still here. Clearing the chrome cache and localstorage and loging in once again, the changed data isn't present any longer.


Can you try this method to update your data (assuming that processgrid variable has been correctly initialized with the record to update if !isNewGrid):

I have a saving dialog with helds the record data. I've a kind of save oder save as new functionality built in. So when the user presses the right button it eigther takes the form's record or if not found tries to find a record in the store or creates a new record



if((record != null) && (record.get('name') == values.name))
processgrid = record;

if(processgrid == undefined)
processgrid = store.getAt(store.findExact('name', values.name));

if(processgrid == undefined) {
processgrid = Ext.create('WischWeb.model.ProcessGrid', {
createDate : new Date(),
user : email
});
} else {
isNewGrid = false;
processgrid.beginEdit();
processgrid.set('changeDate', new Date());
}

processgrid.set({
name : values.name,
orgID : values.orgID
});

simonbrunel
26 Jun 2013, 2:04 AM
Does this last code snippet syncs correctly or is it the code which initially doesn't work?

drindal
26 Jun 2013, 2:41 AM
this is a mixture of the original code and the code, you suggested

edit:
I've looked into your code link. What does store.broadcast() do? When using the sync method from the link, i get following error:
Uncaught TypeError: Object [object Object] has no method 'broadcast'

edit2:
I've looked further into your code and found the answer to my question ;)

simonbrunel
26 Jun 2013, 2:56 AM
So I guess that your code ends with something like that:


[...]
if (isNewGrid) {
store.add(processgrid);
} else {
processgrid.endEdit();
}

store.sync();


Then, I think this should sync correctly - but I didn't get if this new code works or not?

About store.broadcast(), it's a method I added to my store (code here (https://github.com/simonbrunel/jdi/blob/master/application/app/store/Tasks.js#L130)). This is only used to notify other devices to re-sync because server data have changed. This should not impact your data sync issue.

drindal
26 Jun 2013, 3:08 AM
yes my code ends with that:

When you update a record, to you also get following lines in the console?

INFO: SyncProxy.getUpdates: Get updates from CSV: b1-77114508-81, b2-77122703, b3-77120877, b5-77120001, b10-77617944, b13-77702078, b22-78305522, b25-77730414, b28-78305925, b30-78399869, b31-78403541, b32-78404113, b33-0

INFO: SyncProxy.getUpdates: Dominated Replicas:


the only thing is, that filling the processData array happens in a method in the model itself and the rest of the code is in the controller. But this shouldn't matter, i think.

unfortunately the new code doesn't work

drindal
26 Jun 2013, 4:11 AM
So definitely the sync process works, when using set('field', data). The data is also present after doing a complete browser refresh and deleting the cache.

I think, my problem is, when syncing an object (e.g array).

drindal
26 Jun 2013, 6:04 AM
So once again.

I've found a workaround for my array problem.

I use an array of serialized objects, so they appear as string and not as object. Then the sync process is working!