PDA

View Full Version : Callback / JsonWriter Create Response



Bleak
10 May 2010, 7:24 AM
I have implemented a JsonWriter for my datastore, and have setup the various CRUD methods.

My question is;
- After a successful create action, I return a response that contains the original data submitted with proper id values in the defined ID Property. Is the writer supposed to update the data store with the new ids to eliminate the phantom records, or do I need to handle this directly through the onWrite() event?

My create JSON is as follows;


[{"groupId":"2","code":"SPROJ","description":"Senior Project Manager","name":"SR. Project Manager","userId":"1","id":"ext-gen475"}]

My response JSON is as follows;


{"message":"Records Created","success":"true","groups":[{"id":"20","groupId":"2","description":"Senior Project Manager","userId":"1","name":"SR. Project Manager","code":"SPROJ"}]}

Animal
10 May 2010, 7:44 AM
It will "realize" phantoms for you upon receipt of the valid, created records.

Bleak
10 May 2010, 10:30 AM
Hey Animal,

What does that mean? Will it automatically do it, or is there a response format that I need to adhere to that is different that the above? Right now, the response comes back as defined above, but the records remain phantom.

Not sure if I have to run commitChanges() or something like that?

Also, I am using HttpProxy and not ScriptTagProxy so the backend does not return a function. Will this matter?

Thanks,
Dean.

Mike Robinson
10 May 2010, 11:33 AM
Do a Create transaction with an existing demo website and watch the exchanges. Upon a valid response to a 'create' request, the Store will replace the dummy, "phantom" record-IDs with the real ones provided by the host, and will mark the records as "no longer phantom."

Bleak
11 May 2010, 5:12 AM
Thanks Mike, I have done exactly that including the writer example that comes with the extjs distribution. I properly see the create action execute, and from what I can tell my response is properly formatted.



{"message":"Records Created","success":"true","groups":[{"id":"20","groupId":"2","description":"Senior Project Manager","userId":"1","name":"SR. Project Manager","code":"SPROJ"}]}


My reader is configured with the root: 'groups', so I have included the data returned under the groups node. I have the writer configured as listful:true, so I return the data in a list as well. I'm assuming that the reader can handle the listful return.

I have the reader configured with idProperty:id, so the id returned above is also the new id value returned from the server call.

I'm sure its something small, just no luck finding it myself at the moment.

Mike Robinson
11 May 2010, 6:45 AM
One little problem that comes to mind (and I don't rightly recall if it was on the client or the server side or both) is that "lists of one item" might come across as "one item," not a list.

Ahh, yes: here's the reminder-to-myself from the (ColdFusion) client side code:

// Now for the client-side problem. ExtJS sends single-items as ... single items. Whether you specify that a data
// source is "listful" or not, you get a scalar. (Zero items = (empty) array. Two or more = ditto. But just one = scalar.
which I dealt with using this (host-side) ColdFusion function:

function jsonToArray( json_string )
{
var result = ArrayNew(1);
json_string = Trim(json_string);
if (json_string == "") {
result = [];
} else {
if (Mid(json_string, 1, 1) != "[") {
json_string = "[" & json_string & "]";
};
result = DeserializeJSON(json_string);
};
return result;
}Reading further in the list of "reminders to myself," I read this caveat:
DIRE WARNING From the "JsonReader" source code (methods "create" and "update"):
* You <b>must</b> return a complete new record from the server. If you don't, your local record's missing fields
* will be populated with the default values specified in your Ext.data.Record.create specification. Without a defaultValue,
* local fields will be populated with empty string "". So return your entire record's data after both remote create and update.
* In addition, you <b>must</b> return record-data from the server in the same order received.The response packet therefore includes entire records, exactly as ExtJS sent them and in the same order, but with the host-assigned value in the "primary key" (id) slot.

My most lingering memory of building the host-side implementation (now a ColdFusion module known as "InstantCRUD") was that it was quite painful to get it right ... and that every now and then since that time I've found other things slightly wrong with it.

Bleak
11 May 2010, 11:21 AM
I spent some time tracing through the ext-all-debug.js, and I have resolved my issue.. In the Ext.data.HttpProxy class (line 37233) it checks the success attribute of your response;



if (res.success === true) {
this.fireEvent('write', this, action, res.data, res, rs, o.request.arg);
}....
My response was returning "success":"true", instead of "success":true. (no quotes). Once I removed the quotes from the true value of my response, life was good and the store has updated properly.

Quick shoutout to ExtJS and Firebug ;)