-
30 May 2011 1:27 PM #1
[OPEN-125] Store (using AjaxProxy) duplicates new record when .sync() is called
[OPEN-125] Store (using AjaxProxy) duplicates new record when .sync() is called
Sencha Touch version tested:
- 1.1.0
Platform tested against:- iOS 4
- Android 2.1
Description:- New records are duplicated in a store after .sync() is called, when using an AjaxProxy.
Test Case:
Steps to reproduce the problem:Code:// models/contact.js app.models.Contact = new Ext.regModel('Contact', { fields: [ { name: 'id', type: 'int' }, { name: 'first_name', type: 'string' }, { name: 'last_name', type: 'string' }, { name: 'email', type: 'string' }, { name: 'phone', type: 'string' } ], validations: [ { type: 'presence', field: 'first_name', message: 'none' }, { type: 'presence', field: 'last_name', message: 'none' }, { type: 'email', field: 'email', message: 'Please enter a valid e-mail address.' }, { type: 'phone', field: 'phone', message: 'Please enter a valid phone number.'} ], proxy: { type: 'ajax', url: 'contacts.xml', reader: { type: 'xml', record: 'contact' }, writer: { type: 'xml', record: 'contact' } } }); Ext.regStore('contacts', { autoLoad: true, model: 'Contact', sorters: ['last_name'], sortOnLoad: true, getGroupString : function(record) { return (record.get('last_name') || '#')[0].toUpperCase(); }, }); // in views/contacts/list.js app.views.ContactsList = Ext.extend(Ext.Panel, { title: 'Contacts', layout: 'fit', store: 'contacts', initComponent: function () { this.list = new Ext.List({ xtype: 'list', id: 'contactslist', grouped: true, indexBar: true, store: this.store, itemTpl: '{first_name} <strong>{last_name}</strong>' }); this.items = [this.list]; app.views.ContactsList.superclass.initComponent.apply(this, arguments); } }); Ext.reg('contacts/list', app.views.ContactsList); // in controller: var contact = Ext.ModelMgr.create(this.form.getValues(), 'Contact'); var store = Ext.getStore('contacts'); store.add(contact); store.sync(); // Duplicate appears in views list once .sync() asynchronously completes.- Attach a store (backed by an AjaxProxy) to a list
- Add a new (unsaved) record to the same store
- Call .sync() on store
The result that was expected:- List should reflect one new item in the store
The result that occurs instead:- List shows the new item twice
Debugging already done:- Determined that the record returned from the server is never matched against the existing record in the store - because the internalId doesn't match.
Possible fix:- Please see this commit on github for my change to AjaxProxy.js which fixes this for me.
- Note that the list isn't sorted properly within each group after my fix, but that might be the fault of the way I'm sorting things at the moment.
Last edited by mark.haylock; 30 May 2011 at 1:45 PM. Reason: Accidentally submitted the post instead of previewing, so had to complete the post! Sorry.
-
30 May 2011 1:45 PM #2
Questions about bug fixing process and support licenses
Questions about bug fixing process and support licenses
We are currently evaluating Sencha Touch as a platform to move forward with and I've been playing around getting a feel for it's capabilities.
We are pretty keen on what we have seen and will likely purchase a support license, however this duplicate problem caused me some grey hairs, so I have some questions I hope can be answered:
- Is this a bug or have I set up things incorrectly?
- If this is a bug is it fixed in the version available only to support licensees? Is there any public information about what is in the version available only to support licensees?
- If this bug is not fixed in the version available to support licensees then what would be the normal turnaround for such a bug fix to become available (if we had a support license)?
- I notice that in this post you mention "If we get demand for a github repository featuring just the public releases we may set that up too" - can I add a vote for that? It seems that would make submitting fixes like this easier for both sides if we could generate pull requests on github.
-
22 Jun 2011 8:16 AM #3
I noticed this issue too
I noticed this issue too
I experience this issue as well and tracked down the problem.
It's a bug.
Perhaps this override might help someone. It worked for me and my RestProxy.
https://gist.github.com/1040439
Basically, when the DataReader reads a response back from server, it instantiates new record instances, with new internalId set.
When the store has its onWrite callback fired, it tries to replace the original record (which caused the CREATE/UPDATE action) with the new version from server, but it can't possibly find it unless their internalId are set the same.
Code:onProxyWrite: function(operation) { var data = this.data, action = operation.action, records = operation.getRecords(), length = records.length, callback = operation.callback, record, i; if (operation.wasSuccessful()) { if (action == 'create' || action == 'update') { for (i = 0; i < length; i++) { record = records[i]; record.phantom = false; record.join(this); data.replace(record); // <-- HERE. Store tries to replace oldRec with newRec. } } else if (action == 'destroy') { for (i = 0; i < length; i++) { record = records[i]; record.unjoin(this); data.remove(record); } this.removed = []; } this.fireEvent('datachanged'); } //this is a callback that would have been passed to the 'create', 'update' or 'destroy' function and is optional if (typeof callback == 'function') { callback.call(operation.scope || this, records, operation, operation.wasSuccessful()); } },/**
* @author Chris Scott
* @business www.transistorsoft.com
* @rate $120USD / hr; training $500USD / day / developer (5 dev min)
*
* @SenchaDevs http://senchadevs.com/developers/transistor-software
* @twitter http://twitter.com/#!/christocracy
* @github https://github.com/christocracy
*/
-
5 Jul 2011 5:35 PM #4Sencha - Community Support Team
- Join Date
- Jan 2009
- Location
- Palo Alto, California
- Posts
- 1,941
- Vote Rating
- 6
This is a recurring issue with the architecture around creating Model instances locally and saving them remotely. At the moment it's rather difficult to accurately match each record returned by the server against the record we sent to the server.
We're formulating a better solution to this internally at the moment and will keep you updated.Ext JS Senior Software Architect
Personal Blog: http://edspencer.net
Twitter: http://twitter.com/edspencer
Github: http://github.com/edspencer
Thank you for reporting this bug. We will make it our priority to review this report.


Reply With Quote