I have a Kendo UI Grid who's data is being read from a table T1. However, all other Create/Update/Delete operations are being saved to another table T2 along with a field/column 'Operation'. The purpose is to allow an authorized user to review those changes before approving them and updating the record in the original table T1. Therefore, any client-side create/update/delete operation results only an 'insert' operation into table T2. Now here the requirement is that once the server performs its task (inserting the updated model into table T2), the client should remove the model/row/record from the Kendo UI Grid. So once the server completes it's api call it returns the same model back to the client. And on the client-side I am handling the kendo dataSource's requestEnd event to remove the model from the grid. Below code shall give a better idea:
Kendo UI Grid Options:
ctrl.whtRatesMasterGridOptions = {
dataSource: {
type:
'odata'
,
transport: {
read: {
url:
'api/WHTRatesMaster'
,
dataType:
'json'
,
cache:
false
},
create: {
url:
'api/WHTRatesMasterPendingChange'
,
dataType:
"json"
},
update: {
url:
'api/WHTRatesMasterPendingChange'
,
dataType:
"json"
,
type:
"POST"
},
destroy: {
url:
'api/WHTRatesMasterPendingChange'
,
dataType:
"json"
,
contentType:
"application/json"
,
type:
"POST"
},
parameterMap:
function
(options, type) {
if
(type !==
"read"
&& options) {
options.Operation = type;
return
kendo.stringify(options);
}
}
},
requestEnd:
function
(e) {
// ctrl.currentModelUid is set in the grid's edit event.
if
(e.type ===
"create"
|| e.type ===
"update"
) {
// since kendo itself remove's a deleted record from the grid we are only remove the model in case of a 'create' or 'update' operation
var
currentModel = ctrl.whtRatesMasterGrid.dataSource.getByUid(ctrl.currentModelUid);
ctrl.whtRatesMasterGrid.dataSource.remove(currentModel);
}
},
schema: {
data:
function
(data) {
if
(
'Items'
in
data)
return
data.Items;
return
data;
},
total:
function
(data) {
return
data.Count ? data.Count : 0;
},
model: {
id:
"PortfolioCountryEffectiveDateKey"
,
fields: {
PortfolioCountryEffectiveDateKey: { type:
"string"
, editable:
false
, nullable:
false
},
Portfolio: { type:
"string"
, editable:
true
, nullable:
false
, validation: { required:
true
} },
Iso3Code: { type:
"string"
, editable:
true
, nullable:
false
, validation: { required:
true
} },
EffectiveDate: { type:
"date"
, editable:
true
, nullable:
false
, validation: { required: { message:
"Effective Date is required"
} } },
// some more model fields....
}
}
},
},
edit:
function
(e) {
ctrl.currentModelUid = e.model.uid;
},
};
The 'PortfolioCountryEffectiveDateKey' is simply a concatenation of the Portfolio, Iso3Code & the EffectiveDate fields - the server sends it when grid performs a read operation. The database tables have a composite key on these three columns, but since kendo does not have a concept of specifying composite key, I have used such a concatenated property to allow kendo uniquely identify a record in its dataSource by the model.id configuration.
Server-side API:
[Route(
"api/WHTRatesMasterPendingChange"
)]
[ResponseType(
typeof
(WHTRatesMasterPendingChange))]
public
IHttpActionResult WHTRatesMasterPendingChange(WHTRatesMasterPendingChange whtRatesMasterPendingChange)
{
// dbcontext.dbset.Add(whtRatesMasterPendingChange)
return
Ok(whtRatesMasterPendingChange);
}
The signature of the Read API:
public
PageResult<WHTRatesMaster> GetWHTRatesMasterDbSet(ODataQueryOptions options, [FromODataUri]
bool
showActivePortfolios)
Here both the WHTRatesMaster & WHTRatesMasterPendingChange models have a the same composite identity fields (Portfolio, Iso3Code, EffectiveDate).
Problem: The desired functionality ('inserting' records into the table T2 & removing the record from the kendo grid) works well for the CREATE & DESTROY operation. However, when I try to update records, the first request is successful, but for the second request two API calls are made (the first is success, second fails because kendo sends the same model again to the server) - which results in a primary key violation constraint error. So how to I solve the problem of kendo making the same API call twice.
(TO BE NOTED : I am using the same server-side API and type:POST for Create, Update, & Destroy)
EDIT: If I remove the 'requestEnd' event handler, then only single API calls are made to the server. But I also need to remove the updated row from the grid; so don't think I can do away with this event.