PDA

View Full Version : Trouble updating grid with id from server after create extjs 4.2



delebash
22 Apr 2013, 4:12 PM
Using ExtJs 4.2 MVC framework

From my understanding after calling sync on a store that sends a Create ajax using json, it should parse the response and update that record with the new id. I think maybe my problem is with the reader since the database returns an array of records for normal get requests, but only returns 1 record not in an array on a Post response.


Json for normal read into grid


{"__entityModel":"Users","__COUNT":4,"__SENT":4,"__FIRST":0,"__ENTITIES":[{"__KEY":"1","__STAMP":32,"ID":1,"name":"a","email":"[email protected]"},{"__KEY":"13","__STAMP":4,"ID":13,"name":"b","email":"[email protected]"},{"__KEY":"14","__STAMP":3,"ID":14,"name":"c","email":"[email protected]"},{"__KEY":"15","__STAMP":3,"ID":15,"name":"d","email":"[email protected]"}]}


Then I use the root property in the reader on __ENITIES array to get the reocrds, this works fine on a normal GET request.

reader : {
type : 'json',
root : '__ENTITIES',
successProperty: false,
idProperty : '__KEY'
}

This is the response after a CREATE request, no ENITITES array, and I can't change the database response.


{"__KEY":"16","__STAMP":3,"uri":"/rest/Users(16)","ID":16,"name":"a","email":"[email protected]"}

So if this is the case why my record __KEY is not being updated in the grid after a CREATE how do I conditionally specify to not use a root if it is a post response?

This is just my guess as to why my __KEY field is not being updated from the server

Here is full code
Controller

Ext.define('AM.controller.Users', {
extend: 'Ext.app.Controller',
stores: [
'Users'
],
models: [
'User'
],
views: [
'user.List',
'user.Add',
'user.Edit'
],
init: function () {
this.control({
'userlist': {
itemdblclick: this.editUser,
removeitem: this.removeUser
},
'userlist > toolbar > button[action=create]': {
click: this.onCreateUser
},
'useradd button[action=save]': {
click: this.doCreateUser
},
'useredit button[action=save]': {
click: this.updateUser
}
});
},
editUser: function (grid, record) {
var view = Ext.widget('useredit');
view.down('form').loadRecord(record);
},
removeUser: function (user) {
Ext.Msg.confirm('Remove User', 'Are you sure?', function (button) {
if (button == 'yes') {
this.getUsersStore().remove(user);
}
}, this);
},
onCreateUser: function () {
var view = Ext.widget('useradd');
},
doCreateUser: function (button) {
var win = button.up('window'),
form = win.down('form'),
values = form.getValues(),
store = this.getUsersStore();
if (form.getForm().isValid()) {
store.add(values);
win.close();
}
},
updateUser: function (button) {
var win = button.up('window'),
form = win.down('form'),
record = form.getRecord(),
values = form.getValues(),
store = this.getUsersStore();
if (form.getForm().isValid()) {
record.set(values);
win.close();
}
}
});

Model

Ext.define('AM.model.User', {
extend : 'Ext.data.Model',
idProperty : '__KEY',
fields : ['name', 'email', '__KEY', '__STAMP']
});


Store

var crudServiceBaseUrl = "http://127.0.0.1:8081/cors/";

Ext.define('AM.store.Users', {
extend : 'Ext.data.Store',
model : 'AM.model.User',
autoLoad : true,
autoSync : true,
proxy : {
idProperty : '__KEY',
type : 'ajax',
api : {
create : crudServiceBaseUrl + 'Users/?$method=update',
read : crudServiceBaseUrl + 'Users',
update : crudServiceBaseUrl + 'Users/?$method=update',
destroy : crudServiceBaseUrl + 'Users/?$method=delete'
},
writer : {
type : 'json',
writeAllFields : false,
getRecordData : function(record, operation) {
switch(operation.action) {
case 'create':
console.log('INFO', 'Create');
delete record.data.__KEY
delete record.data.__STAMP
return record.data
break;
case 'update':
console.log('INFO', 'Updating');
var myrecord = record.getChanges();
myrecord.__KEY = record.data.__KEY
myrecord.__STAMP = record.data.__STAMP
return myrecord
break;
}
},
},
reader : {
type : 'json',
root : '__ENTITIES',
successProperty: false,
idProperty : '__KEY'
}

},
update : function(record, operation, modifiedFieldNames, eOpts) {
// debugger;
console.log("records");
},
onCreateRecords : function(records, operation, success) {
console.log(records);
},

onUpdateRecords : function(records, operation, success) {
// debugger;
// console.log(records);
},

onDestroyRecords : function(records, operation, success) {
console.log(records);
},
listeners : {
update : function(store, record, operation, eOpts) {
switch(operation) {
case Ext.data.Model.EDIT:
console.log('INFO', 'Updating record...');
break;
case Ext.data.Model.COMMIT:
console.log('INFO', 'Record was updated!');
break;
case Ext.data.Model.REJECT:
console.log('ERR', 'Something went horribly wrong :( Data was rejected!');
break;
}
},
beforesync : function(options, eOpts) {
// debugger;
}
}
// listeners : {
// write : function(store, action, result, res, rs) {
// debugger;
// console.log('WRITE', arguments);
// }
// },
})

Thanks, Dan

slemmon
24 Apr 2013, 7:32 AM
There's not a conditional reader config to allow for the reader to parse the returned data one way for one operation and one way for another. For the reader to read data into the store it'll look for the data format to be the same on each return.

delebash
24 Apr 2013, 1:37 PM
Thanks, I figured out a way to handle my scenerio, basically determines if its an array by seeing if __ENTITIES is present, else just a single entity then manually turn into an array of __ENTITIES


reader : {
type : 'json',
root : '__ENTITIES',
successProperty : false,
idProperty : '__KEY',
getResponseData : function(response) {
var findme = "__ENTITIES";
if (response.responseText.indexOf(findme) > -1) {
//Already an array of __ENTITIES
} else {
//Single result turn into array __ENTITIES
response.responseText = '{"__ENTITIES":[' + response.responseText + ']}' ;
}
var data = Ext.data.reader.Json.prototype.getResponseData.call(this, response);
return data;
}
}

}