- Home
- Forum
- JavaScript - EJ 2
- Manual refresh of the Grid's data with 'offline' data for client-side processing (e.g., filtering)
Manual refresh of the Grid's data with 'offline' data for client-side processing (e.g., filtering)
Hello together,
I want to use the Grid component with client-side processing for user actions, such as Sorting, Filtering, etc.
Therefore, I tried to accomplish this with the WebAPIAdapter using offline-mode as well as with the RemoteSaveAdapter.
In both ways, I can't trigger a refresh of the Grid's content.
When using the RemoteSaveAdapter, the data is properly sent to the server and the newly added entry is properly shown based on the data received from server after adding.
But I can't trigger a manual refresh of the data in the Datagrid, e.g., after another user has added data in parallel.
I've tested it with manually fetching the data and assign the newly received data to the dataManager's json attribute, but nothing happened. Also an invocation of the grids refresh method didn't refresh the shown content.
Secondly, I've tested it with the WebApiAdapter using the offline-mode, i.e. setting "offline: true" on the DataManager.
In this scenario, an invocation of grid.refresh() doesn't send any request to the server for new data. Also here, changing to "offline: false" for before invoking grid.refresh didn't change anything.
For this setting, I had additionally the issue, that with adding new data, the inserted data is properly shown locally in the client, but also here, nothing is sent to the server.
I assume, for such a scenario, the RemoteSaveAdapter is more appropriate, but also there, I didn't manage to trigger a refresh of the data.
Is there a way, to perform a forced refresh of the data using one of the mentioned DataManager alternatives, without reloading the entire page ?
Thank you very much in advance!
Kind regards,
cornelius
Hi Cornelius,
Greetings from Syncfusion support.
Upon reviewing your query, we have found that in the first scenario, if the RemoteSaveAdaptor is utilized, the grid actions will be executed on the client side, while the CRUD operations will be carried out on the server side. When a record is inserted, a request is sent to the server, and as a result, the grid will be entirely refreshed with the updated data in order to update the pager based on the viewport, which is the default behavior.
In the second scenario, you have mentioned that you are using the WebApiAdaptor with offline mode set to true. In this case, data binding in the grid will be treated as local data, and no request will be made to the server. All grid actions will only be performed on the client side.
Therefore, please provide the following information to assist us in offering a better solution:
1. Since the grid is automatically refreshed after inserting the data, please specify the exact requirement for which you need to force a refresh of the grid.
2. In the example you have provided the "another user adding data in parallel," - are you attempting to notify the changes to all users while updating the records parallelly?
Please find the detailed information in our documentation using the following link:
WebApiAdaptor : https://ej2.syncfusion.com/javascript/documentation/grid/data-binding/remote-data#web-api-adaptor
Offline mode: https://ej2.syncfusion.com/javascript/documentation/grid/data-binding/remote-data#offline-mode
RemoteSaveAdaptor: https://ej2.syncfusion.com/javascript/documentation/grid/data-binding/remote-data#remote-save-adaptor
Regards
Aishwarya R
Hello Aishwarya,
thanks for your answer und explanation!
They confirm, what I've understood so far from the documentation of the DataManager-Adapters.
Let me try to better explain my scenario and requirements:
My primary use case requirements are the following:
1. Operations such as searching, filtering, sorting is handled at the client.
2. Added or modified data is sent immediately to the server.
3. User can manually trigger a data refresh, or another example, server notifies the client using WebSocket about new/modified data, and the Grid can fetch this new dataset (without reloading the entire page, which would be the "hard" solution contradicting user experience principles)
Due to the first requirement, I had a look at the RemoteSaveAdapter, as well as the WebApiAdapter in offline-Mode.
Of course, for really large datasets, it is absolutely valid to perform actions such as searching, filtering or paging at the server-side.
But for rather small datasets (let's say for example, datasets with less than 1000 entries) it's not necessary nowadays (client systems are performant enough) and introduces remarkable delays and interferences (e.g., using smartphones with mobile internet), contradicting to user experience UX requirements.
The second requirement basically prohibits the WebApiAdapter in offline-mode, because as you confirmed "All grid actions will only be performed on the client side." In non-offline-mode, the first requirement is conflicted.
Basically, the third requirement is a description referring to both your questions.
As scenario example: another user might add or modify data in parallel or the server-application itself might process data (periodically or based on some trigger events in the server application) and add or modify existing data, which the client-application or the user might want to fetch, i.e. reload the data manually or based on some "notification-event" from the server.
But of course, reloading here refers to just reloading the data, not reloading the entire webpage or web application.
I hope, I could answer your questions ?!
Thank you very much for your assistance!
Kind regards,
Cornelius
Hi Cornelius Moucha,
As per your requirement, the Grid actions such as searching, filtering, and sorting are to be performed on the client side. These actions will not be reflected when multiple users modify the data, as they are only carried out on the client side and do not affect the original JSON data initially bound to the Grid. However, it is necessary to display any added or modified data to other users who may be working in parallel.
In the RemoteSaveAdaptor, CRUD operations are handled on the server side. Similar to other operations, these actions do not impact the original JSON data. We are currently validating your requirement with the RemoteSaveAdaptor and will provide an update on or before February 23rd, 2024. Until then, we appreciate your patience and understanding.
Please confirm whether you only require the actions such as searching, filtering, and sorting to be performed on the client side.
Regards
Aishwarya R
Hello Aishwarya,
thank you for your answer!
Indeed, your description of my scenario is correct:
- Grid actions such as searching, filtering, sorting or paging or to be handled on client side as these actions do not modify the data itself but just reflect the representation of the data in the client
- adding or modifying, i.e. real modification of the underlying data itself has to be handled on the server-side for persisting these changes and to be reflected also to other users working on the same grid in their client application
For the second requirement (adding or modifying), I use RemoteSaveAdapter, as you have described.
But I need a technique to update/reload the original JSON data of other clients without reloading the entire webpage.
Thank you and kind regards,
Cornelius
Hi Cornelius,
Thank you for your patience and for providing more details about your requirement.
Based on the provided details, we understand that your primary requirement is to reload the dataSource of the Grid with DataManager, which utilizes RemoteSaveAdaptor. You can achieve this by creating a new instance of DataManager with RemoteSaveAdaptor and fetching data every time data reload is needed. Please find the code snippet below for your reference:
|
[Views\Home\Index.cshtml]
// fetching data and bind it to the Grid via RemoteSaveAdaptor // call this method every time data reload needed async function fetchData() { // Base API URL const baseURL = "Home/RemoteSaveDataSource";
// fetching data from server using fetch request const response = await fetch(baseURL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, });
// await the response data const data = await response.json();
// the response data to the DataManager with RemoteSaveAdaptor // and then bind the DataManager instance to the Grid grid.dataSource = new ej.data.DataManager({ adaptor: new ej.data.RemoteSaveAdaptor(), insertUrl: "/Home/Insert", updateUrl: "/Home/Update", removeUrl: "/Home/Delete", json: data, }); }
|
Regarding the requirement to reflect the changes to every user if the server gets updated, we have implemented a solution that utilizes SignalR to notify all clients about the server-side update. Based on this update, we will fetch the data again from the server and bind it to the new DataManager instance, and then assign it to the Grid dataSource. We have created a working sample implementing this by using JavaScript EJ2 Grid on the client side and ASP.Net Core on the server side. Please find the steps involving the procedure to implement SignalR with the above-configured project for your reference below:
- Need
to add a dependency for SignalR on both Client and Server sides:
Add CDN reference or script reference of SignalR on the client side:
|
[Views\Shared\_Layout.cshtml]
<head> . . . . . <!— SignalR CDN à <script src=https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/8.0.0/signalr.min.js integrity=”sha512-7rhBJh1om/W5Ztx7WiYOR9h2wlSaTmPyQMoHFtbT/FVNIA12y6S6I8HY9mrBS1uJ3dSU/R3qaSAXsGYuRjMDxg==” crossorigin=”anonymous” referrerpolicy=”no-referrer”> </script> </head>
|
For the server side, add the package "Microsoft.AspNetCore.SignalR"
through .NET CLI.
- Create
a SignalR hub:
Create a SignalR hub that will handle the real-time communication. Please find a simple hub that is utilized in our sample for your reference below:
|
[GridUpdateHub.cs]
using Microsoft.AspNetCore.SignalR;
public class GridUpdateHub : Hub { public async Task SendGridUpdateNotification() { await Clients.All.SendAsync("ReceiveGridUpdate"); } }
|
- Configure SignalR in Program.cs or Startup.cs:
|
[Program.cs]
// Add SignalR service builder.Services.AddSignalR();
. . . . .
app.UseEndpoints(endpoints => { endpoints.MapHub<GridUpdateHub>("/gridUpdateHub"); // Map SignalR hub endpoint endpoints.MapControllers(); // Add this line if you want to use controller endpoints });
|
- Modify
your controller methods to send update notifications:
Configure all the CRUD method on server side to send notification to clients through SignalR service.
|
[Controllers\HomeController.cs]
public IActionResult Insert([FromBody] CRUDModel<Orders> value, [FromServices] IHubContext<GridUpdateHub> hubContext) { order.Insert(0, value.Value);
// send notification to connected clients through SignalR hubContext.Clients.All.SendAsync("ReceiveGridUpdate");
return Json(value.Value); }
|
- Client-side integration:
|
[Views\Home\Index.cshtml]
// creating instance of signalR connection builder // CDN reference added in "Shared/_Layout.cshtml" head tag var connection = new signalR.HubConnectionBuilder() .withUrl("/gridUpdateHub") .configureLogging(signalR.LogLevel.Information) .build();
// start the connection connection.start().then(function () { console.log("SignalR connected."); }).catch(function (err) { return console.error(err.toString()); });
// notification listener for server update connection.on("ReceiveGridUpdate", function () { // reload the data from server and bind to the Grid fetchData(); });
|
With these changes, the Grid will now refresh automatically whenever an update occurs on the server side. Make sure your client and server configurations are aligned, and SignalR endpoints are accessible from the client-side code.
Attached below are the GIF demonstration and sample for your reference.
Please let us know if you
have any further queries or require additional assistance.
Regards,
Santhosh I
Attachment: CoreGridApp_4e05fe99.zip
Hello Santhosh,
thank you very much for your assistance and provided example !
I appreciate your work !
Your solution works very good for me.
One final question:
In your example, you have reinstantiated the new DataManager with the new data (in the fetchData method) directly on the grid.dataSource.
Is the previous assigned DataManager automatically cleaned up from the client's memory or do I have to invoke some "destroy" or similar method on the old DataManager instance ?
Thank you very much for your assistance,
Cornelius
Hi Cornelius,
By default, when you assign a new object to a reference that previously pointed to another object, the old object is no longer accessible via that reference. If there are no other references to the old object elsewhere in your code, it becomes unreachable, and the garbage collector will eventually reclaim the memory occupied by that object. The same principle applies to the DataManager instance. Once a new instance of DataManager is assigned to the dataSource property of the Grid, the old DataManager instance will no longer have any references to it and cannot be accessed from elsewhere, eventually being freed up from memory.
However, if you don’t want to create a new instance of DataManager every time a CRUD action is performed on the Grid, then instead of this approach, you can directly create the DataManager instance during the initial render when the Grid is created, without the “json” property. You can then bind the data through the “dataSource.dataSource.json” property and refresh the Grid. This ensures that the Grid is populated with loaded data. Please find the modified code snippet and sample attached below for your reference:
|
[Views\Home\Index.cshtml]
<script> // configure Grid let grid = new ej.grids.Grid({ dataSource: new ej.data.DataManager({ adaptor: new ej.data.RemoteSaveAdaptor(), insertUrl: "/Home/Insert", updateUrl: "/Home/Update", removeUrl: "/Home/Delete", }),
. . . . .
created: created });
. . . . .
// triggers when Grid is created function created() { // begin fetching data for initial render fetchData(); }
// fetching data and bind it to the Grid via RemoteSaveAdaptor // call this method every time data reload needed async function fetchData() { // Base API URL const baseURL = "Home/RemoteSaveDataSource";
// fetching data from server using fetch request const response = await fetch(baseURL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, });
// await the response data const data = await response.json();
// bind the fetched data to the Grid dataSource grid.dataSource.dataSource.json = data;
// refresh the Grid to populate the Grid with new data grid.refresh(); } </script>
|
Regards,
Santhosh I
Attachment: CoreGridApp_b4d89ee8.zip
Hi Santhosh,
thank you very much for you answer and additional work !!
Kind regards and thank you again,
Cornelius
Hi Cornelius Moucha,
Thanks for the update.We are glad that the solution met your requirement. Please get back to us for further assistance.
Regards,
Dineshnarasimman M
- 9 Replies
- 4 Participants
-
CM Cornelius Moucha
- Jan 19, 2024 02:08 PM UTC
- Mar 12, 2024 03:19 AM UTC