This is a migrated thread and some comments may be shown as answers.

Update and Create in Grid throws "Unable to get property 'data' of undefined or null reference"

9 Answers 1062 Views
Grid
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Raymond
Top achievements
Rank 1
Raymond asked on 18 Mar 2015, 01:20 AM
I am trying to update and create records in the grid but I get the error "Unable to get property 'data' of undefined or null reference" whenever I click "Update".

My grid is defined in the HTML as;

<div class="row">
    <ul class="nav nav-tabs" style="margin-bottom: 10px;">
        <li class="active"><a data-toggle="tab" href="#Users">Users</a></li>
        <li><a data-toggle="tab" href="#Reports">Reports</a></li>
        <li><a data-toggle="tab" href="#Sections">Sections</a></li>
        <li><a data-toggle="tab" href="#Charts">Charts</a></li>
    </ul>
    <div class="tab-content">
        <div id="Users" class="tab-pane fade in active">
            <kendo-grid options="userGridOptions"></kendo-grid>
        </div>
        <div id="Reports" class="tab-pane fade">
            <h3>Report Maintenance</h3>
        </div>
        <div id="Sections" class="tab-pane fade">
            <h3>Section Maintenance</h3>
        </div>
        <div id="Charts" class="tab-pane fade">
            <h3>Chart Maintenance</h3>
        </div>
    </div>
</div>

The script to define the grid options is;

$scope.userGridOptions = {
    dataSource: {
        transport: {
            read: "/Home/GetUsers",
            dataType: "json",
            type: "POST"
        },
        update: {
            url: "/Home/UpdateUser",
            dataType: "json",
            type: "POST"
        },
        create: {
            url: "/Home/UpdateUser",
            dataType: "json",
            type: "POST"
        },
        parameterMap: function (data, operation) {
            if (operation !== "read") {
                return kendo.stringify(data);
            }
        },
        batch: false,
        pageSize: 15,
        schema: {
            model: {
                id: "id",
                fields: {
                    id: { type: "number", editable: false, nullable: true, defaultValue: 0 },
                    loginName: { type: "string", validation: { required: true } },
                    firstName: { type: "string", validation: { required: true } },
                    lastName: { type: "string", validation: { required: true } },
                    position: { type: "string", validation: { required: true } },
                    email: { type: "string", validation: { required: true } },
                    active: { type: "boolean", validation: { required: true }, defaultValue: true},
                    updatedBy: { type: "string", editable: false, nullable: true },
                    updatedDtTm: { type: "date", editable: false, nullable: true },
                    rowVersion: { type: "string", editable: false, nullable: true },
                }
            }
        }
    },
    height: "500px",
    selectable: "row",
    filterable: true,
    sortable: true,
    pageable: true,
    toolbar: ["create"],
    editable: {
        mode: "inline",
        update: true,
        destroy: false
    },
    columns: [
        { field: "id", title: "User ID" }, //, width: "60px"
        { field: "active", title: "Active", template: '<input type="checkbox" #= active ? "checked=checked" : ""#></input>' }, //width: "80px",
        { field: "loginName", title: "Login Name" }, //, width: "250px"
        { field: "firstName", title: "First Name" }, //, width: "200px"
        { field: "lastName", title: "Last Name" }, //, width: "200px"
        { field: "position", title: "Position" }, //, width: "200px"
        { field: "email" },
        { command: ["edit"], title: " "}
    ]
};

And the procedures called to read, update and create data are (the stored procedure will insert the record if ID=0);

public ActionResult GetUsers()
{
    List<User> lstUsers = new List<User>();
    var users = from rt in ctx.tblUsers orderby rt.NameLast, rt.NameFirst select rt;
    try
    {
        foreach (var item in users)
        {
            User userItem = new User();
            userItem.ID = item.ID;
            userItem.LoginName = item.NameLogin;
            userItem.FirstName = item.NameFirst;
            userItem.LastName = item.NameLast;
            userItem.Position = item.Title;
            userItem.Email = item.Email;
            userItem.Active = item.Active;
            userItem.UpdatedBy = item.UpdatedBy;
            userItem.UpdatedDtTm = item.UpdatedDtTm;
            userItem.RowVersion = item.RowVersion;
            lstUsers.Add(userItem);
        }
        return GetJsonResult(lstUsers);
    }
    catch (Exception ex)
    {
        List<string> errors = new List<string>();
        errors.Add(ex.Message);
        if (ex.InnerException != null) errors.Add(ex.InnerException.Message);
        return new HttpStatusCodeResult(HttpStatusCode.InternalServerError, string.Join("<br />", errors));
    }
}
 
public ActionResult UpdateUser(User UserData)
{
    try
    {
        var results = ctx.usp_Users_Update(UserData.ID, UserData.LastName, UserData.FirstName, UserData.LoginName, UserData.Position, UserData.Email, UserData.Active, UserData.UpdatedBy, UserData.UpdatedDtTm, UserData.RowVersion);
        return GetJsonResult(results);
    }
    catch (Exception ex)
    {
        List<string> errors = new List<string>();
        errors.Add(ex.Message);
        if (ex.InnerException != null) errors.Add(ex.InnerException.Message);
        return new HttpStatusCodeResult(HttpStatusCode.InternalServerError, string.Join("<br />", errors));
    }
}

When I click "Update" from the grid I get the error reported above, the actual code breaks in kendo.all.min.js at "o=ut(r.data)?r.data(e.data):r.data".  Examining the variables shows the "e.data" contains the updated data from the grid but "r" is undefined.

I have tried modifying code based on several examples from the Telerik product demos and documentation as well some responses in the forums but without any success.  I'm not clear on the purpose of the "parameterMap" option and have just tried various different code examples in an attempt to get this to work.

Any help on this would be appreciated.

9 Answers, 1 is accepted

Sort by
0
Rosen
Telerik team
answered on 19 Mar 2015, 01:12 PM
Hello Raymond,

By looking at the provided snippets I suspect that the error you are getting is caused by incorrect declaration configuration. The update, create and parameterMap settings are declared outside of the transport configuration. The correct transport configuration should look similar to the following:

dataSource: {
  transport: {
    read: {
      url: "/Home/GetUsers",
      dataType: "json",
      type: "POST"
    },
    update: {
      url: "/Home/UpdateUser",
      dataType: "json",
      type: "POST"
    },
    create: {
      url: "/Home/UpdateUser",
      dataType: "json",
      type: "POST"
    },
    parameterMap: function (data, operation) {
      if (operation !== "read") {
        return kendo.stringify(data);
      }
    },
  },
 
  batch: false,
  /*...*/
}

The purpose of the parameterMap is to format the request parameters in the correct format, required by the server endpoint in order to correctly deserialize them into the appropriate server-side structure.

Regards,
Rosen
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Raymond
Top achievements
Rank 1
answered on 23 Mar 2015, 12:07 AM
Hi Rosen,

You were right - the read section was malformed.

I have since found out the create and update sections are incorrect as they currently stand so I have updated my code as follows;

01.$scope.userGridOptions = {
02.    dataSource: {
03.        transport: {
04.            read: function (options) {
05.                $.ajax({
06.                        url: "/Home/GetUsers",
07.                        dataType: "json",
08.                        success: function (result) {
09.                            options.success(result);
10.                        }
11.                });
12.            },
13.            update: function (options) {
14.                $.ajax({
15.                    url: "/Home/UpdateUser",
16.                    dataType: "json",
17.                    type: "post",
18.                    data: options.data,
19.                    success: function (result) {
20.                        options.success(result);
21.                    },
22.                    error: function (result) {
23.                        options.error(result)
24.                    }
25.                });
26.            },
27.        },
28.        batch: false,
29.        pageSize: 15,
30.        schema: {
31.            model: {
32.                id: "id",
33.                fields: {
34.                    id: { type: "number", editable: false, nullable: true, defaultValue: 0 },
35.                    loginName: { type: "string", validation: { required: true } },
36.                    firstName: { type: "string", validation: { required: true } },
37.                    lastName: { type: "string", validation: { required: true } },
38.                    position: { type: "string", validation: { required: true } },
39.                    email: { type: "string", validation: { required: true } },
40.                    active: { type: "boolean", validation: { required: true }, defaultValue: true },
41.                    updatedBy: { type: "string", editable: false, nullable: true },
42.                    updatedDtTm: { type: "date", editable: false, nullable: true },
43.                    rowVersion: { type: "string", editable: false, nullable: true },
44.                }
45.            }
46.        }
47.    },
48.    height: "500px",
49.    selectable: "row",
50.    filterable: true,
51.    sortable: true,
52.    pageable: true,
53.    toolbar: ["create"],
54.    editable: { mode: "popup", update: true, destroy: false },
55.    columns: [
56.        { field: "active", title: "Active", width: "100px", attributes: { class: "cbCentre" }, template: '<input type="checkbox" #= active ? "checked=checked" : ""#></input>' },
57.        { field: "loginName", title: "Login Name", width: "200px", filterable: false },
58.        { field: "firstName", title: "First Name", width: "125px" },
59.        { field: "lastName", title: "Last Name", width: "125px" },
60.        { field: "position", title: "Position", width: "180px" },
61.        { field: "email", title: "Email", width: "200px", filterable: false },
62.        { command: ["edit"], title: " " }
63.    ]
64.};

The problem I have now is when I edit the record using the popup option and select update the grid row is blanked out (except for the email column).  If I then select edit again, the popup form is displayed with the blank fields but if I select cancel the original data is then displayed in the grid.  If I then refresh the screen the updated data is displayed; see the attached images.

In the update section do I need to do more then call "option.success(result);"?  What else should I be doing?

Regards,
0
Raymond
Top achievements
Rank 1
answered on 23 Mar 2015, 12:22 AM
0
Raymond
Top achievements
Rank 1
answered on 23 Mar 2015, 12:42 AM
Are there any non-trivial examples (including server-side MVC controllers) in the documentation that fully exercise the datasource options.

I find the current documentation disjointed in that you have to follow numerous links in order to get a full understanding of all of the options and features.  For example; the CRUD example provides a complete example of of CRUD operations with local data but not with remote data.  The Datasource page provides links to Datasource Overview and Basic Usage neither of which explain that except for the most trivial of purposes the;

dataSource: {
    transport: {
        read: "/Home/GetUsers",
        dataType: "json",
        type: "POST"
    },
    update: {
        url: "/Home/UpdateUser",
        dataType: "json",
        type: "POST"
    },
    create: {
        url: "/Home/UpdateUser",
        dataType: "json",
        type: "POST"
    }

examples will NOT work in a real world environment where data is returned to the client containing updated data that must then be reflected in UI.

In short the current documentation leaves much to be desired.
0
Accepted
Rosen
Telerik team
answered on 23 Mar 2015, 08:01 AM
Hi Raymond,

Most probably the cause for the blank row is incorrect data returned by the update service endpoint. I suspect that the service is returning an empty object (or the result is not in the correct format Please verify this for example by observing the server response using Chrome network tab of the developer tools.

Regarding the documentation. The article you have pointed contains information about CRUD operations using remote operations as well as contains links to runnable examples on CRUD operations using different server-side technologies. 

Regards,
Rosen
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Raymond
Top achievements
Rank 1
answered on 25 Mar 2015, 01:48 AM
Hi Rosen,

Again you were correct - the data returned contained additional fields which appeared to causing the problem.  Once I removed these fields the row was refreshed correctly.
0
Aaron
Top achievements
Rank 1
answered on 22 Apr 2016, 11:00 PM

Rosen,

I have a grid that only contains ONE column (for now) which ALWAYS contains a value.  If I understand your comment:

"Most probably the cause for the blank row is incorrect data returned by the update service endpoint. I suspect that the service is returning an empty object"

Why is the error in question, "0x800a138f - JavaScript runtime error: Unable to get property 'sortable' of undefined or null reference' thrown?  There are OTHER columns in the Model associated w/the Kendo().Grid that CAN be NULL but if I am not exposing them in the .Columns section.  I doubt that it matters because I have other Kendo().Grids that have similar Models where I do not see that error.

0
Aaron
Top achievements
Rank 1
answered on 22 Apr 2016, 11:01 PM

Rosen,

Please see my question below.  I should have posted the question as a reply to this specific comment.

0
Rosen
Telerik team
answered on 25 Apr 2016, 06:08 AM

Hello Aaron,

I'm not sure how your question is related to the topic discussed in this thread, nor it provides enough information to guess what the cause for the described behavior is. Thus, I would ask you to open a separate  support request in which to provide as much information as possible - a small runnable sample which demonstrates the issue will be appreciated. 

Regards,
Rosen
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
Tags
Grid
Asked by
Raymond
Top achievements
Rank 1
Answers by
Rosen
Telerik team
Raymond
Top achievements
Rank 1
Aaron
Top achievements
Rank 1
Share this question
or