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

Thread is closed for posting
10 posts, 1 answers
  1. Raymond
    Raymond avatar
    65 posts
    Member since:
    Oct 2013

    Posted 17 Mar 2015 Link to this post

    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.
  2. Rosen
    Admin
    Rosen avatar
    3253 posts

    Posted 19 Mar 2015 Link to this post

    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!
     
  3. Raymond
    Raymond avatar
    65 posts
    Member since:
    Oct 2013

    Posted 22 Mar 2015 in reply to Rosen Link to this post

    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,
  4. Raymond
    Raymond avatar
    65 posts
    Member since:
    Oct 2013

    Posted 22 Mar 2015 in reply to Raymond Link to this post

    Forgot to attach the files...
  5. Raymond
    Raymond avatar
    65 posts
    Member since:
    Oct 2013

    Posted 22 Mar 2015 in reply to Raymond Link to this post

    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.
  6. Answer
    Rosen
    Admin
    Rosen avatar
    3253 posts

    Posted 23 Mar 2015 Link to this post

    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!
     
  7. Raymond
    Raymond avatar
    65 posts
    Member since:
    Oct 2013

    Posted 24 Mar 2015 in reply to Rosen Link to this post

    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.
  8. Aaron
    Aaron avatar
    20 posts
    Member since:
    Jan 2015

    Posted 22 Apr 2016 Link to this post

    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.

  9. Aaron
    Aaron avatar
    20 posts
    Member since:
    Jan 2015

    Posted 22 Apr 2016 in reply to Rosen Link to this post

    Rosen,

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

  10. Rosen
    Admin
    Rosen avatar
    3253 posts

    Posted 25 Apr 2016 Link to this post

    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!
     
Back to Top