Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EXT Js Complex JSON Response Handling : Grid Insertion

Hello I am trying to insert a JSON record into the grid dynamically. My server response is as below :

{
    "studentDetails":{
        "status":"ACTIVE",
        "subject":"MATH",
        "paymentOptions":"EFT",
        "idStudent":71,
        "firstName":"Alli",
        "lastName":"Alli",
        "middleName":"Alli",
        "grade":"A",
        "kumonLevel":"FK",
        "parentId":68,
        "userId":1,
        "parentBean":{
            "parentFirstName":"Alli",
            "idParent":68,
            "parentMiddleName":"Alli",
            "parentLastName":"Alli",
            "parentEmailId":"[email protected]",
            "parentPhoneNumber":"3173797945"},
        "startTimeSlot":"12:00 AM",
        "endTimeSlot":"12:15 AM",
        "dob":"2012-07-04"},
    "success":true
}

A student having parentDetails as a seperate object in the above response.

at my client I did the following : i had a grid with the below configuration :

var studentRecord = Ext.data.Record.create( [ {
    name : 'firstName',
    type : 'string'
}, {
    name : 'lastName',
    type : 'string'
}, {
    name : 'middleName',
    type : 'string'
}, {
    name : 'grade',
    type : 'string'
}, {
    name : 'kumonLevel',
    type : 'string'
}, {
    name : 'startTimeSlot',
    type : 'string'
}, {
    name : 'endTimeSlot',
    type : 'string'
}, {
    name : 'subject',
    type : 'string'
}, {
    name : 'dob',
    type : 'date'
}, {
    name : 'status',
    type : 'string'
}, {
    name : 'paymentOptions',
    type : 'string'
}, {
    name : 'parentFirstName',
    mapping : 'parentBean.parentFirstName',
    type : 'string'
}, {
    name : 'parentLastName',
    mapping : "parentBean['parentLastName']",
    type : 'string'
}, {
    name : 'parentMiddleName',
    mapping : 'parentBean.parentMiddleName',
    type : 'string'
}, {
    name : 'parentPhoneNumber',
    mapping : 'parentBean.parentPhoneNumber',
    type : 'String'
}, {
    name : 'parentEmailId',
    mapping : 'parentBean.parentEmailId',
    type : 'string'
} ]);

var myProxy = new Ext.data.HttpProxy( {
    method : 'GET',
    url : 'listActiveStudents.do'
});
var studentsListReader = new Ext.data.JsonReader( {
    successProperty : 'success',
    root : 'studentDetails',
    idProperty : 'idStudent'
}, studentRecord);

var studentDS = new Ext.data.Store( {
    proxy : myProxy,
    autoLoad : true,
    totalProperty : 'total',
    reader : studentsListReader
});

upon data receiving from the server I did the following :

handler : function() {
    studentForm.getForm().submit({
        url : 'createStudent.do',
        waitMsg : 'Saving Data...',
        submitEmptyText : false,
        success : function(form, action) {
            win.close();
            var studentDetail = action.result.studentDetails;
            var xyz = new studentDS.recordType(studentDetail, 0);
            studentDS.insert(0,xyz);
        }
    });
}

The problem what I am facing here is :

When the record is inserted the parentDetails are not showing up in the grid. Seems, the mapping is not working properly while inserting. Where as while loading the grid initially it renders perfectly. I created the record well which shows in firefox debbuger with valid values too.

could any one guide me please?

like image 303
Gopi Kancharla Avatar asked May 25 '26 07:05

Gopi Kancharla


1 Answers

This is a very tricky issue. but I found an easy (but dirty) solution, which you just need to edit the line where you create your record, from this:

var xyz = new studentDS.recordType(studentDetail, 0);

to this:

var xyz = new studentDS.recordType(
    studentDS.reader.extractValues(
        studentDetail, 
        studentDS.fields.items,
        studentDS.fields.length
    ), studentDetail.idStudent); //use the idStudent of the studentDetail, so the id of the newly created record equals to your idStudent

And here is why

So after tracing the calling stack, I found an interesting differences between the records you loaded from Store, and the record that you created through your new studentDS.recordType.

Look at the differences:

//This is the record created from Store Load event
    dob: Wed Jul 04 2012 00:00:00 GMT+0800 (Malay Peninsula Standard Time)
    endTimeSlot: "12:15 AM"
    firstName: "Alli"
    grade: "A"
    kumonLevel: "FK"
    lastName: "Alli"
    middleName: "Alli"
    parentEmailId: "[email protected]"
    parentFirstName: "Alli"
    parentLastName: "Alli"
    parentMiddleName: "Alli"
    parentPhoneNumber: "3173797945"
    paymentOptions: "EFT"
    startTimeSlot: "12:00 AM"
    status: "ACTIVE"
    subject: "MATH"
    __proto__: Object

//This is the record created from your studentDS.recordType
    dob: "2012-07-04"
    endTimeSlot: "12:15 AM"
    firstName: "Alli"
    grade: "A"
    idStudent: 80
    kumonLevel: "FK"
    lastName: "Alli"
    middleName: "Alli"
    parentBean: Object
        idParent: 68
        parentEmailId: "[email protected]"
        parentFirstName: "Alli"
        parentLastName: "Alli"
        parentMiddleName: "Alli"
        parentPhoneNumber: "3173797945"
        __proto__: Object
    parentId: 68
    paymentOptions: "EFT"
    startTimeSlot: "12:00 AM"
    status: "ACTIVE"
    subject: "MATH"
    userId: 1
    __proto__: Object

In fact, while you load your data, your JsonStore and JsonReader did a dirty hack to your loaded data. They linearize your data. They move all your data from your parentBean to the root of the record.data, so while rendering the grid, your grid can be rendered correctly.

To know how they render your grid, check the code at Line 827 of GridView.js

meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);

Notice how the GridView is capturing the values. They use record.data[column.name] to get the value of each fields, and this is where all your parent* report undefined.

And so to know how they linearize your codes, you can check line 157 of DataReader.js

var record = new Record(this.extractValues(n, fi, fl), this.getId(n));
//where:
//n = your raw json object
//fi = the field items
//fl = the field length

And in fact the new Record they used here is identical with your new studentDS.recordType, with the exception that they extractValues for you on behalf, and clearly you did not do it because it's not obvious to do so.

Got it? Hope the explanation is clear enough.

like image 158
Lionel Chan Avatar answered May 26 '26 22:05

Lionel Chan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!