transport.update: only add changed fields in the request body

3 posts, 0 answers
  1. Cory
    Cory avatar
    13 posts
    Member since:
    Nov 2014

    Posted 13 Jun Link to this post

    Hi, 

     

    I'd like to perform an odata PATCH operation where only the dirty fields are sent in the request body.The code below is my latest attempt, but the grid continues to send the full set of fields. If I omit the data/type sections of the update option, then I get a PUT request with the full set of fields.

    My other attempt involved omitting the update altogether and overriding the saveChanges event to make the request myself, but then I run into issues with dirty fields staying dirty. I know you can mess around with the css to remove the flags, but the datasource fields stay dirty and end up getting updated again the next time the saveChanges event is triggered.

    Is there a way to let the grid know that the saveChanges event was successful so that it handles the dirty flags on its own? Another solution?

    Thanks.

     

     
    transport: {
        read: {
            url: serviceURL + entity.ClassName
        },
        update: {
            url: function (data) {
                var key = "(" + data.ID + "," + data.NetworkID + "," + data.From + "," + data.To + ")";
     
                return serviceURL + entity.ClassName + key;
             },
             type: "PATCH",
             data: function (data) {
                             
            var row = $("#elementGrid").data("kendoGrid").dataSource.get(data.ID);
     
            var updateData = {};
     
            $.each(row.dirtyFields, function (key, value) {
                updateData[key] = row[key];
            });
     
            return updateData;
        }
       }
    }
  2. Cory
    Cory avatar
    13 posts
    Member since:
    Nov 2014

    Posted 14 Jun Link to this post

    I forgot to mention that I've also tried setting up the read and update as functions, but then I ran into issues with the odata expressions not being applied automatically to the read url ($skip/$top/etc).

    I tried getting them from the options parameter, which actually worked pretty well until I got to the filter property. Is there an easy way to convert the field/operator/value objects into qualified odata $filter strings without having to manually build them? It wouldn't be the end of the world having to go that route, but I was hoping not to have to deal with deciding whether or not to quote the value.

  3. Angel Petrov
    Admin
    Angel Petrov avatar
    1075 posts

    Posted 15 Jun Link to this post

    Hello,

    In order to remove the unneeded properties one can use the parameterMap function. Here is an example that removes the UnitPrice field from the object that represents the grid row modified data.

    transport: {
                                   .....
                                    parameterMap: function(options, operation) {
                                        if (operation !== "read") {
                                            delete options.UnitPrice;
     
                                            return options;
                                        
                                    }
                                },
                                pageSize: 20,
                                schema: {
                                    model: {
                                        id: "ProductID",
                                        fields: {
                                            ProductID: { editable: false, nullable: true },
                                            ProductName: { validation: { required: true } },
                                            UnitPrice: { type: "number", validation: { required: true, min: 1} },
                                            Discontinued: { type: "boolean" },
                                            UnitsInStock: { type: "number", validation: { min: 0, required: true } }
                                        }
                                    }
                                }

    As for converting a filter to an OData filter you can use the OData parameterMap public function. Here is an example.

    kendo.data.transports["odata"].parameterMap({ filter: { filters: [ {field: "ProductName", operator: "eq", value: "test"} ] } }, "read")


    Regards,
    Angel Petrov
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top