Grid batch save event and send updated values to server via POST HttpClient

Hi, 

I need to know how do I get updated values from my grid into the component. I need the modified records to be sent to server as json object as POST request which will be persisted and then i need to refresh the grid with new modified data
I am using editMode as 'batch'. Is there any event i can use on click of in-built toolbar Update button? Thanks!

COMPONENT TS
this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Batch' };
this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];

APP COMPONENT HTML
<ejs-grid #grid [dataSource]='data' [editSettings]='editSettings'[toolbar]='toolbar' (rowSelected)= "rowSelected($event)" >
<e-columns>
<e-column field="name" headerText="Name" [isPrimaryKey]='true' width="120"></e-column>
<e-column field="volSigma" headerText="Sigma" width="140"></e-column>
<e-column field="daysRange" headerText="Days Range" width="130"></e-column>
</e-columns>


16 Replies

MS Madhu Sudhanan P Syncfusion Team October 5, 2018 07:33 AM UTC

Hi Samir, 

You can achieve your requirement by using the ‘beforBatchSave’ event of Grid component in which you can get the modified data and send the POST request to update the data in server. We have prepared a simple sample based on your requirement. Please refer to the below code example , Documentation link and sample link. 

[component.ts] 
@Component({ 
    selector: 'fetchdata', 
    template: ` <ejs-grid [dataSource]='data' [editSettings]='editSettings' (beforeBatchSave)="batchSave($event)" [toolbar]='toolbar' height='273px'> 
    <e-columns> 
        .  .  . 
    </e-columns> 
</ejs-grid>`, 
}) 
export class FetchDataComponent { 
      .  .  . 
 
    ngOnInit(): void { 
        this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Batch' }; 
        this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel']; 
        .  . . 
    } 
    batchSave(e: any) { 
        var data = { 
            action: 'batch', Changed: e.batchChanges.changedRecords, Added: e.batchChanges.addedRecords, Deleted: e.batchChanges.deletedRecords 
        } 
        var ajax = new Ajax(); 
        ajax.data = JSON.stringify(data); 
        ajax.url = "/Home/BatchUpdate"; 
        ajax.type = "POST"; 
        (ajax as any).contentType = "application/json; charset=utf-8"; 
        (ajax as any).successHandler = function (data:any) { 
            // you can refresh the grid here with new data 
            this.grid =data; 
        } 
        ajax.send(); 
    }    
} 
 




Regards, 
Madhu Sudhanan P 



SM Samir Modi October 5, 2018 08:13 AM UTC

Thanks Sudhanan for your reply. I could achieve this using (beforeBatchSave)="batchSave($event)" that you mentioned. One follow up question -

How do I cancel all my batch changes if the POST api fails for some reason. I tried using this.grid.editModule.batchCancel() in my batchSave method but it is not reverting the values in the grid. I do not want to get the previous data back using another GET request if the POST fails.

onBeforeBatchSave(event) {
        let record: any;
        var jsonObj = [];
        //if POST throws error , revert updated values on the grid
        this.grid.editModule.batchCancel();


MS Madhu Sudhanan P Syncfusion Team October 8, 2018 06:22 AM UTC

Hi Samir, 

You can achieve your requirement by using the following way. In this solution, we have canceled the batch save action initially and if the AJAX request is success, We have re-called the batchSave() method otherwise we called closeEdit() method to discard the changes. Please refer to the below code example, Documentation link and sample link. 

[component.ts] 
@Component({ 
    selector: 'fetchdata', 
    template: ` <ejs-grid #grid [dataSource]='data' [editSettings]='editSettings' (beforeBatchSave)="beforeBatchSave($event)" [toolbar]='toolbar' height='273px'> 
    <e-columns> 
        .  .  . 
    </e-columns> 
</ejs-grid>`, 
}) 
export class FetchDataComponent { 
    .  .  . 
    beforeBatchSave(e: any) { 
        const comp = this; 
        if (comp.flag) { 
            e.cancel = true;         
            let data = { 
                action: 'batch', Changed: e.batchChanges.changedRecords, Added: e.batchChanges.addedRecords, Deleted: e.batchChanges.deletedRecords 
            } 
            var ajax = new Ajax(); 
            ajax.data = JSON.stringify(data); 
            ajax.url = "/Home/BatchUpdate"; 
            ajax.type = "POST"; 
            (ajax as any).contentType = "application/json; charset=utf-8"; 
            (ajax as any).successHandler = function (data: any) { 
                comp.flag = false; 
                 // calling the batchSave() method if the Ajax success 
                (comp.grid.editModule as any).editModule.batchSave(); 
                comp.flag  = true; 
            }; 
            (ajax as any).failureHandler = function (data: any) { 
                 // close the Edit state if the AJAX fails 
                comp.grid.closeEdit(); 
            }; 
            ajax.send(); 
        } 
    } 
    
} 

                              https://ej2.syncfusion.com/angular/documentation/grid/api-edit.html#batchsave  


Regards, 
Madhu Sudhanan P 



SA Sahal replied to Madhu Sudhanan P January 5, 2019 11:17 AM UTC

Hi Samir, 

You can achieve your requirement by using the following way. In this solution, we have canceled the batch save action initially and if the AJAX request is success, We have re-called the batchSave() method otherwise we called closeEdit() method to discard the changes. Please refer to the below code example, Documentation link and sample link. 

[component.ts] 
@Component({ 
    selector: 'fetchdata', 
    template: ` <ejs-grid #grid [dataSource]='data' [editSettings]='editSettings' (beforeBatchSave)="beforeBatchSave($event)" [toolbar]='toolbar' height='273px'> 
    <e-columns> 
        .  .  . 
    </e-columns> 
</ejs-grid>`, 
}) 
export class FetchDataComponent { 
    .  .  . 
    beforeBatchSave(e: any) { 
        const comp = this; 
        if (comp.flag) { 
            e.cancel = true;         
            let data = { 
                action: 'batch', Changed: e.batchChanges.changedRecords, Added: e.batchChanges.addedRecords, Deleted: e.batchChanges.deletedRecords 
            } 
            var ajax = new Ajax(); 
            ajax.data = JSON.stringify(data); 
            ajax.url = "/Home/BatchUpdate"; 
            ajax.type = "POST"; 
            (ajax as any).contentType = "application/json; charset=utf-8"; 
            (ajax as any).successHandler = function (data: any) { 
                comp.flag = false; 
                 // calling the batchSave() method if the Ajax success 
                (comp.grid.editModule as any).editModule.batchSave(); 
                comp.flag  = true; 
            }; 
            (ajax as any).failureHandler = function (data: any) { 
                 // close the Edit state if the AJAX fails 
                comp.grid.closeEdit(); 
            }; 
            ajax.send(); 
        } 
    } 
    
} 

                              https://ej2.syncfusion.com/angular/documentation/grid/api-edit.html#batchsave  


Regards, 
Madhu Sudhanan P 


Hi Madhu Sudhanan  

Is there a similar way for dialog edit mode in angular

What I need is an ability to save the record to the server on the save button of the dialog and then close the dialog if the operation was successful, else show the error.

While adding / updating a record the server responds with the created/updated record. I want to update the grid with this single record, instead of fetching all the records once again


MS Madhu Sudhanan P Syncfusion Team January 7, 2019 12:40 PM UTC

Hi Sahal, 

Thanks for contacting Syncfusion support. 

We can achieve the same behavior using the actionBegin event for the dialog edit mode as follows. 


@Component({  
    selector: 'fetchdata',  
    template: ` <ejs-grid #grid [dataSource]='data' [editSettings]='editSettings' (actionBegin)="actionBegin($event)" [toolbar]='toolbar' height='273px'>  
    <e-columns>  
        .  .  .  
    </e-columns>  
</ejs-grid>`,  
})  
export class FetchDataComponent {  
    .  .  .  
    actionBegin(e: any) {  
        const comp = this;  
        if (comp.flag) {  
            e.cancel = true;                     
            var ajax = new Ajax();  
            ajax.data = JSON.stringify(e.data);  
            ajax.url = "/Home/Update";  
            ajax.type = "POST";  
            (ajax as any).contentType = "application/json; charset=utf-8";  
            (ajax as any).successHandler = function (data: any) {  
                comp.flag = false;  
                 // calling the endEdit() method if the Ajax success  
                (comp.grid.editModule as any).editModule.endEdit();  
                comp.flag  = true;  
            };  
            (ajax as any).failureHandler = function (data: any) {  
                 // close the Edit state if the AJAX fails  
                comp.grid.closeEdit();  
            };  
            ajax.send();  
        }  
    }  
     
}  




Regards, 
Madhu Sudhanan P 



SA Sahal January 8, 2019 11:19 AM UTC

Thank You Madhu Sudhanan  

Works great!




MS Madhu Sudhanan P Syncfusion Team January 8, 2019 12:07 PM UTC

Hi Sahal, 
Thanks for the update. We are glad that the requirement has been achieved. 
Regards, 
Madhu Sudhanan P 



SA Sahal replied to Madhu Sudhanan P January 26, 2019 04:43 AM UTC

Hi Sahal, 

Thanks for contacting Syncfusion support. 

We can achieve the same behavior using the actionBegin event for the dialog edit mode as follows. 


@Component({  
    selector: 'fetchdata',  
    template: ` <ejs-grid #grid [dataSource]='data' [editSettings]='editSettings' (actionBegin)="actionBegin($event)" [toolbar]='toolbar' height='273px'>  
    <e-columns>  
        .  .  .  
    </e-columns>  
</ejs-grid>`,  
})  
export class FetchDataComponent {  
    .  .  .  
    actionBegin(e: any) {  
        const comp = this;  
        if (comp.flag) {  
            e.cancel = true;                     
            var ajax = new Ajax();  
            ajax.data = JSON.stringify(e.data);  
            ajax.url = "/Home/Update";  
            ajax.type = "POST";  
            (ajax as any).contentType = "application/json; charset=utf-8";  
            (ajax as any).successHandler = function (data: any) {  
                comp.flag = false;  
                 // calling the endEdit() method if the Ajax success  
                (comp.grid.editModule as any).editModule.endEdit();  
                comp.flag  = true;  
            };  
            (ajax as any).failureHandler = function (data: any) {  
                 // close the Edit state if the AJAX fails  
                comp.grid.closeEdit();  
            };  
            ajax.send();  
        }  
    }  
     
}  




Regards, 
Madhu Sudhanan P 


Hi 

Although this solution works, the data returned cannot be updated to the grid.

Meaning the primarykey id is not updated to the row. The server returns the inserted/ updated row. 

What is the mechanism to update the grid's specific row with the new data from the server



TS Thavasianand Sankaranarayanan Syncfusion Team January 28, 2019 11:22 AM UTC

Hi Sahal, 
 
Query: Although this solution works, the data returned cannot be updated to the grid. Meaning the primarykey id is not updated to the row. The server returns the inserted/ updated row. What is the mechanism to update the grid's specific row with the new data from the server 
 
We have validated your query and by default the edited data is updated in the grid when you call endEdit method. Could you please share the below details, it will be helpful to provide a better solution. 
 
  • Bind actionFailure event to grid and share the error details, if any error throws.
  • Share grid code example or sample if it is possible.
  • Are you process edited values in server side and the update the processed values in grid?
 
Regards, 
Thavasianand S. 



SA Sahal replied to Thavasianand Sankaranarayanan February 4, 2019 10:43 AM UTC

Hi Sahal, 
 
Query: Although this solution works, the data returned cannot be updated to the grid. Meaning the primarykey id is not updated to the row. The server returns the inserted/ updated row. What is the mechanism to update the grid's specific row with the new data from the server 
 
We have validated your query and by default the edited data is updated in the grid when you call endEdit method. Could you please share the below details, it will be helpful to provide a better solution. 
 
  • Bind actionFailure event to grid and share the error details, if any error throws.
  • Share grid code example or sample if it is possible.
  • Are you process edited values in server side and the update the processed values in grid?
 
Regards, 
Thavasianand S. 


I think you did not understand my requirement. The data which was entered by the user is being saved to the grid when the end edit is called. 
What is not being saved is the Id of the newly created record that the server returns. Please see my code below for further understanding;

actionBegin(args: SaveEventArgs): void {
if (args.requestType === 'beginEdit' || args.requestType === 'add') {
this.item = <Item>args.rowData;//Object.assign({}, args.rowData);

}

if (args.requestType === 'save') {
const comp = this;
if (comp.flag) {
args.cancel = true;

if (this.itemForm.valid) {
this.itemService.upsert(this.item).subscribe(i => {
//this is the row data (i) the server returns after inserting it to the database. It will contain the id(primary key ) generated by the server
args.data = i;
comp.flag = false;
(comp.grid.editModule as any).editModule.endEdit();
comp.flag = true;
//alert("Sucess")
},
error => {

comp.grid.closeEdit();
comp.flag = true;
alert(error);

})

} else {
args.cancel = true;
}
}
}
}


MS Madhu Sudhanan P Syncfusion Team February 6, 2019 12:41 PM UTC

Hi Sahal, 

To troubleshoot this problem, could you please share the request and their response sent during the edit and the following refresh operation. A request will be send after the edit operation to refresh the grid content, please share the server response of that particular issue to check whether the Id value is present.  

Regards, 
Madhu Sudhanan P 




GM Gangabharathy Murugasen Syncfusion Team February 7, 2019 05:41 AM UTC

This is the request to add a new Item 
 
 
this is the data returned by the server with ItemId 1026 
 
 
When I try to edit it and save , the item id is null (meaning it did not save to grid) and hence the server will insert new row and return a new Id. 
 
 
But the grid will show as if the edit has been saved 
 
 
But after reloading the grid again, it will show 2 rows 
 
 
Now if I edit any of the above rows it will work as the grid has been reloaded and the id fields correctly in place 



SA Sahal February 20, 2019 10:44 AM UTC

Could any one update on this..

@MadhuSudhanan
The post by Gangabharathy Murugasen is actully my reply to your query for the details. I wasn't able to reply to the thread and hence mailed to the support email


MS Madhu Sudhanan P Syncfusion Team February 22, 2019 04:10 PM UTC

Hi Sahal, 

Sorry for the delay in get back to you. 

Please modify the actionBegin handler as below to resolve the problem. In the below code example, we have used addRecord if the action is add. Now the grid will be updated with data from the server. 


actionBegin(args: SaveEventArgs): void { 
    if (args.requestType === 'beginEdit' || args.requestType === 'add') { 
      this.item = <Item>args.rowData;//Object.assign({}, args.rowData); 
 
    } 
 
    if (args.requestType === 'save') { 
      const comp = this; 
      if (comp.flag) { 
        args.cancel = true; 
 
        if (this.itemForm.valid) { 
         
          this.itemService.upsert(this.item).subscribe(i => { 
//this is the row data (i) the server returns after inserting it to the database. It will contain the id(primary key ) generated by the server 
            args.data = i; 
            comp.flag = false; 
            if (args.action === 'add') { 
                comp.grid.editModule.addRecord(args.data, 0); 
              } else { 
                (comp.grid.editModule as any).editModule.endEdit(); 
              } 
            comp.flag = true; 
            //alert("Sucess") 
          }, 
            error => { 
              comp.grid.closeEdit(); 
              comp.flag = true; 
              alert(error); 
 
            }) 
 
        } else { 
          args.cancel = true; 
        } 
      } 
    } 
  } 




Regards, 
Madhu Sudhanan P 



SA Sahal February 22, 2019 04:23 PM UTC

Thanks Madhu

Works great!

Thanks a lot


MS Madhu Sudhanan P Syncfusion Team February 22, 2019 04:28 PM UTC

Hi Sahal, 
  
We are glad that your requirement has been achieved. 
  
Regards, 
Madhu  
  


Loader.
Up arrow icon