Success! Looks like we've fixed this one. According to our records the fix was applied for TOUCH-1980 in a recent build.
  1. #1
    Sencha Premium Member
    Join Date
    Oct 2011
    Location
    Paris, France
    Posts
    187
    Vote Rating
    3
    olouvignes is on a distinguished road

      0  

    Default [b2] read proxy broken when using resultSet

    [b2] read proxy broken when using resultSet


    I reported a few days ago that setting an empty resultSet crashed during the callback on a proxy read operation : http://www.sencha.com/forum/showthre...ultSet-crashes

    It looks like it is not caused by an empty resultSet, just got the same crash with actual records in my resultSet.

    I guess that is is caused by a probably broken "operation.getRecords()" that return null (onProxyLoad() l.48463) while there is records in the resultset.

  2. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    36,795
    Vote Rating
    834
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    That would tell me that you may not have the reader setup to map to your records.

    Can I get a runnable test case so that we can pinpoint the issue so we can make sure it gets fixed?
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  3. #3
    Sencha Premium Member
    Join Date
    Oct 2011
    Location
    Paris, France
    Posts
    187
    Vote Rating
    3
    olouvignes is on a distinguished road

      0  

    Default


    Here is a full test crashing on b2 :

    Code:
    window.d = true;
    window.app = {
    	ns: 'MyApp'
    };
    
    
    Ext.application({
    
    
    	name: app.ns,
    	controllers: [],
    	stores: ['ContactList'],
    	//views: ['Viewport'],
    
    
    	launch: function() {
    		d&&console.log(app.ns + '.application#launch', [this, arguments]);
    
    
    		// Create Viewport
    		this.viewport = Ext.create(app.ns + '.view.Viewport');
    	},
    
    
    	getViewport: function() {
    		return this.viewport;
    	}
    
    
    });
    
    
    
    Ext.define(app.ns + '.view.Viewport', {
    
    
    	id: 'viewport',
    	extend: 'Ext.Container',
    
    
    	config: {
    		layout: {
    			type: 'card',
    			animation: {type: 'slide'}
    		},
    		fullscreen: true
    	},
    
    
    	initialize: function() {
    		this.callParent();
    		d&&console.log(Ext.getDisplayName(arguments.callee), [this, arguments]);
    
    
    		this.add([
    			{xtype: 'contact-test'}
    		]);
    
    
    	}
    
    
    });
    
    
    
    
    Ext.define(app.ns + '.view.Contacttest', {
    
    
    	id: 'contact-test',
    	alias: 'widget.contact-test',
    	extend: 'Ext.Panel',
    
    
    	config: {
    		scrollable: false
    	},
    
    
    	initialize: function() {
    		this.callParent();
    		d&&console.log(Ext.getDisplayName(arguments.callee), [this, arguments]);
    
    
    		// Configure component
    		this.add([
    			{
    			xtype: 'container',
    			items:[
    			{
    				xtype: 'fieldset',
    				style: 'margin:4%;',
    				items: [
    				{
    					xtype: 'button',
    					text: 'test',
    					action: 'test',
    					style: 'margin:4%;',
    					handler: function() {
    						Ext.getStore('ContactList').load({ callback: function(records, operation, success) {
    							console.warn('callback');
    						}});
    					}
    				}
    				]
    			}
    			]
    			}
    		]);
    
    
    	}
    
    
    });
    
    
    
    
    
    
    Ext.define(app.ns+'.model.proxy.ContactProxy', {
    
    
        extend: 'Ext.data.Proxy',
    	alias: 'proxy.contact-proxy',
    
    
    	deviceFields: ['id', 'displayName', 'name', 'emails', 'phoneNumbers', 'addresses', 'birthday', 'organizations', 'urls'],
    
    
    	create: function(operation, callback, scope) {
    	},
    	read: function(operation, callback, scope) { d=true;
    		var self = this, displayName;
    		d&&console.log(displayName = Ext.getDisplayName(arguments.callee), [this, arguments]);
    
    
    		operation.setStarted();
    
    
    		var processDeviceContacts = function(deviceContacts) {
    
    
    			// Loop over deviceContacts and create Contact model instances
    			var contacts = [];
    			for (var i = 0; i < deviceContacts.length; i++) {
    				var deviceContact = deviceContacts[i];
    				d&&console.log(JSON.stringify(deviceContact));
    
    
    				// Force strings
    				if(!deviceContact.name.familyName) deviceContact.name.familyName = '';
    				if(!deviceContact.name.givenName) deviceContact.name.givenName = '';
    
    
    				// Require one name
    				if(!deviceContact.name.familyName && !deviceContact.name.givenName) continue;
    
    
    				var boundModel = self.getModel();
    				var contact = new boundModel(deviceContact);
    
    
    				contact.deviceContact = deviceContact;
    				contacts.push(contact);
    				d&&console.log(displayName + ' ~ Importing new contact from deviceContact.', [contact, deviceContact]);
    			}
    
    
    			// Return model instances in a result set
    			operation.setResultSet(new Ext.data.ResultSet({
    				records: contacts,
    				total  : contacts.length,
    				loaded : true
    			}));
    
    
    			// Announce success
    			operation.setSuccessful();
    			operation.setCompleted();
    			// Finish with callback
    			if (typeof callback == 'function') {
    				console.warn('about to crash... ', operation);
    				callback.call(scope, operation);
    			}
    
    
    		};
    
    
    		if(!navigator || !navigator.hasOwnProperty('contacts')) {
    
    
    			// Fixture
    			var deviceContacts = [
    				JSON.parse('{"id":1,"displayName":null,"name":{"givenName":"Olivier","formatted":"Olivier Test","middleName":null,"familyName":"Test","honorificPrefix":null,"honorificSuffix":null},"nickname":null,"phoneNumbers":[{"type":"mobile","value":"+33 6 05 22 62 00","id":0,"pref":false}],"emails":[{"type":"home","value":"tests@gmail.com","id":0,"pref":false}],"addresses":null,"ims":null,"organizations":null,"birthday":null,"note":null,"photos":null,"categories":null,"urls":null}'),
    				JSON.parse('{"id":2,"displayName":null,"name":{"givenName":"Abott","formatted":"Abott","middleName":null,"familyName":null,"honorificPrefix":null,"honorificSuffix":null},"nickname":null,"phoneNumbers":[{"type":"mobile","value":"+1 (23 )","id":0,"pref":false}],"emails":null,"addresses":null,"ims":null,"organizations":null,"birthday":null,"note":null,"photos":null,"categories":null,"urls":null}')
    			];
    			processDeviceContacts(deviceContacts);
    
    
    		} else {
    
    
    			// Phonegap
    			var options = new ContactFindOptions();
    			options.filter = operation.filter || '';
    			options.multiple = true;
    
    
    			//d&&console.log('navigator.contacts.find', [self.deviceFields, options]);
    			navigator.contacts.find(self.deviceFields,
    				processDeviceContacts,
    				function (error) {
    					throw new Error('Something went wrong during Phonegap.contacts.find() operation.');
    				},
    				options
    			);
    		}
    
    
    		return operation;
    
    
    	},
    	update: function(operation, callback, scope) {
    	},
    	destroy: function(operation, callback, scope) {
    	}
    });
    
    
    
    
    Ext.define(app.ns + '.model.Contact', {
    
    
    	extend: 'Ext.data.Model',
    
    
    	config: {
    
    
    		fields: [
    			{name: "id", type: "int"},
    			{name: "displayName", type: "string"},
    			{name: "firstName", type: "auto"},
    			{name: "lastName", type: "auto"},
    			{name: "name", type: "auto"}, // ContactName[formatted, familyName, givenName, middleName, honorificPrefix, honorificSuffix]
    			{name: 'sortName', type: 'string', convert: function(v, record) { return record.data.name.familyName || record.data.name.givenName || '#';}},
    			//{name: "nickname", type: "string"}, // would create "" in iPhone
    			{name: "phoneNumbers", type: "auto"}, // ContactField[id, pref, type, value]
    			{name: "emails", type: "auto"}, // ContactField[id, pref, type, value]
    			{name: "addresses", type: "auto"}, //ContactAddresses [id, pref, type, country, locality, postalCode, region, streetAddress]
    			{name: "ims", type: "auto"}, // ContactField[id, pref, type, value]
    			{name: "organizations", type: "auto"}, // ContactOrganization[id, pref, type, name, department, value]
    			{name: "birthday", type: "date"},
    			{name: "note", type: "string"},
    			{name: "photos", type: "auto"}, // ContactField[id, pref, type, value]
    			{name: "categories", type: "auto"}, // ContactField[id, pref, type, value]
    			{name: "urls", type: "auto"} // ContactField[id, pref, type, value]
    		],
    
    
    		proxy: {
    			type: "contact-proxy"
    		}
    
    
    	}
    });
    
    
    
    
    Ext.define(app.ns + '.store.ContactList', {
    
    
    	id: 'ContactList',
    
    
    	extend: 'Ext.data.Store',
    
    
    	config: {
    
    
    		model: app.ns + '.model.Contact',
    
    
    		groupField: 'sortName',
    		groupDir: 'DESC',
    		groupFn : function(record) {
    			return record.get('sortName')[0].toUpperCase();
    		}
    
    
    	}
    
    
    });

  4. #4
    Sencha User
    Join Date
    Mar 2007
    Location
    Haarlem, Netherlands
    Posts
    1,243
    Vote Rating
    10
    TommyMaintz will become famous soon enough TommyMaintz will become famous soon enough

      0  

    Default


    Hi olouvignes,

    I would recommend looking at the WebStorage.js file, as it is a perfect example of what every operation in a Proxy needs to do. In your case, you are not setting the records on the operation itself. After you set the resultSet, if you would add the line operation.setRecords(contacts) it would work as expected.

    For the next release I have made a little shortcut in the operation.getRecords() method that will check in the resultSet for records. This allows your example to run without adding anything, and is similar to what the old data package used to do.

    Hope this answers your question.

  5. #5
    Sencha Premium Member
    Join Date
    Oct 2011
    Location
    Paris, France
    Posts
    187
    Vote Rating
    3
    olouvignes is on a distinguished road

      0  

    Default


    Thanks Tommy, it did not cross my mind that i could check on ST-core proxy class. Glad to find out that this is not as bad as it looked ;-).

    By the way, looking at WebStorage.js I do not find "operation.setStarted();", is it deprecated/useless or should I keep it in my code?

    Thanks,

  6. #6
    Sencha User
    Join Date
    Mar 2007
    Location
    Haarlem, Netherlands
    Posts
    1,243
    Vote Rating
    10
    TommyMaintz will become famous soon enough TommyMaintz will become famous soon enough

      0  

    Default


    Tbh it is pretty useless I didn't call it in the WebStorage proxy since it is a synchronous operation. If you have an asynchronous process to get your records, calling operation.setStarted will allow people to query the Operation object to see if its currently in progress. Calling setSuccessful and setCompleted is important though since it is checked for in the Store.

Turkiyenin en sevilen filmlerinin yer aldigi xnxx internet sitemiz olan ve porn sex tarzi bir site olan mobil porno izle sitemiz gercekten dillere destan bir durumda herkesin sevdigi bir site olarak tarihe gececege benziyor. Sitenin en belirgin ozelliklerinden birisi de Turkiyede gercekten kaliteli ve muntazam, duzenli porno izle siteleri olmamasidir. Bu yuzden iste. Ayrica en net goruntu kalitesine sahip adresinde yayinlanmaktadir. Mesela diğer sitelerimizden bahsedecek olursak, en iyi hd porno video arşivine sahip bir siteyiz. "The Best anal porn videos and slut anus, big asses movies set..." hd porno faketaxi