SignalR datasource with server sorting/filtering

7 posts, 0 answers
  1. Inge
    Inge avatar
    15 posts
    Member since:
    Jul 2013

    Posted 12 Jan 2018 Link to this post

    Hi,

    I have a Kendo Grid that is using a SignalR datasource. The grid is also using server filtering, paging and sorting. Paging works fine, however filtering and sorting don't. 

    Here is the JavaScript datasource:

    01.this.datasourceLog = await new kendo.data.DataSource({
    02.            type: "signalr",
    03.            transport: {
    04.                signalr: {
    05.                    hub: hubLog,
    06.                    promise: hubStart,
    07.                    server: {
    08.                        read: "read",
    09.                        create: "create"
    10.                    },
    11.                    client: {
    12.                        read: "read",
    13.                        create: "create"
    14.                    }
    15.                }
    16.            },
    17.            push: (e) => {
    18.                let items = this.datasourceLog.data();
    19. 
    20.                let n = items.pop();
    21.                items.pop();
    22.                items.unshift(n);
    23.            },
    24.            pageSize: 10,
    25.            serverPaging: true,
    26.            serverFiltering: true,
    27.            serverSorting: true,
    28.            schema: {
    29.                total: "total",
    30.                data: "data",
    31.                model: {
    32.                    fields: {
    33.                        customer: { type: "string" },
    34.                        timestamp: { type: "date" },
    35.                        machine: { type: "string" },
    36.                        action: { type: "string" },
    37.                        info: { type: "string" },
    38.                        data2: { type: "string" }
    39.                    }
    40.                }
    41.            },
    42.            sort: { field: "timestamp", dir: "desc" }
    43.        });

    And here is the server side method in the SignalR Hub:

    1.public async Task<DataSourceResult> Read(DataSourceRequest request)
    2.        {
    3.            return (await new LogRepository().GetLogsAsync()).ToDataSourceResult(request);
    4.        }

     

    As you can see, the method in the Hub does not use the DataSourceRequestModelBinder from Telerik, because modelbinders can't be used in a SignalR hub. This is also the reason why server sorting and filtering doesn't work, because the modelbinder changes the fields in the DataSourceRequest from 'sort' to 'Sorts' and 'filter' to 'Filters'. 

    What the client sends to the server for example (link is from another grid):

    api/customer/get?take=10&skip=0&page=1&pageSize=10&sort%5B0%5D%5Bfield%5D=companyName&sort%5B0%5D%5Bdir%5D=asc

    While the server requests a DataSourceRequest object containing the fields 'Sorts' and 'Filters'.

     

    I have also tried to change the properties in the ParameterMap method:

    1.parameterMap: function(options, type) {
    2.                    if(type === "read"){
    3.                        (<any>options).filters = options.filter;
    4.                        (<any>options).sorts = options.sort;
    5.                    }
    6.                    return options;
    7.                }

     

    Then the 'Sorts' property in the DataSourceRequest object actually contains data, but however this is still not correct because the property 'Member' in the Kendo.Mvc.SortDescriptor is null (see attached file).

     

    And I get an error:

    [11:07:13 GMT+0100 (Romance Standard Time)] SignalR: At least one object must implement IComparable.
       at System.Collections.Comparer.Compare(Object a, Object b)
       at System.Collections.Generic.ObjectComparer`1.Compare(T x, T y)
       at System.Linq.EnumerableSorter`2.CompareKeys(Int32 index1, Int32 index2)
       at System.Linq.EnumerableSorter`1.QuickSort(Int32[] map, Int32 left, Int32 right)
       at System.Linq.EnumerableSorter`1.Sort(TElement[] elements, Int32 count)
       at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__1.MoveNext()
       at System.Linq.Enumerable.<SkipIterator>d__30`1.MoveNext()
       at System.Linq.Enumerable.<TakeIterator>d__24`1.MoveNext()
       at Kendo.Mvc.Extensions.QueryableExtensions.Execute[TModel,TResult](IQueryable source, Func`2 selector)
       at Kendo.Mvc.Extensions.QueryableExtensions.CreateDataSourceResult[TModel,TResult](IQueryable queryable, DataSourceRequest request, ModelStateDictionary modelState, Func`2 selector)
       at Kendo.Mvc.Extensions.QueryableExtensions.ToDataSourceResult(IEnumerable enumerable, DataSourceRequest request)
       at LicensingServer.API.Helpers.LogHub.<Read>d__0.MoveNext() in C:\Projects\LicensingServer\Aurelia\LicensingServerAPI\LicensingServer.API\Helpers\LogHub.cs:line 21
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at Microsoft.AspNet.SignalR.Hubs.HubPipelineModule.<>c__DisplayClass0_0.<<BuildIncoming>b__0>d.MoveNext().

     

    Any help or suggestions are welcome.

     

     

  2. Stefan
    Admin
    Stefan avatar
    3008 posts

    Posted 16 Jan 2018 Link to this post

    Hello, Inge,

    Indeed, the Kendo UI ToDataSource request does not work out of the box with the SingnalR and server filtering and sorting due to the specific format of the requests.

    I can suggest checking the following example demonstrating how the desired result can be achieved. The example is using MVC, but the core logic is similar:

    https://www.telerik.com/forums/working-demo-of-grid-using-signalr-databinding-with-serverside-sorting-filtering-and-paging

    I hope this is helpful.

    Regards,
    Stefan
    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.
  3. Inge
    Inge avatar
    15 posts
    Member since:
    Jul 2013

    Posted 16 Jan 2018 Link to this post

    Hi Stefan,

    Thank you for your answer. The solution was indeed to work with a custom DataSourceRequest and using .ToDataSourceResult(request.Take, request.Skip, request.Sort, request.Filter, request.Aggregates). 

     

    Maybe an idea to put this in the documentation? I'm sure other people will have this problem as well.

    Regards,

    Inge

  4. Stefan
    Admin
    Stefan avatar
    3008 posts

    Posted 16 Jan 2018 Link to this post

    Hello, Inge,

    I'm glad to hear that the example was helpful.

    The main idea why this is not working out of the box and it is not documented is because we do not recommend using the Kendo UI Grid, SignalR and operations as filtering as in a real-world application when multiple users are working on the same Grid, every filter will send a notifications making the Grid nearly unusable due to the multiple notifications that will pop up when the user is trying to interact with the Grid.

    We recommend using SignalR mostly for displaying purposes where changes are coming from the database and the users only monitor the results without interacting with the Grid.

    Regards,
    Stefan
    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.
  5. Phil
    Phil avatar
    3 posts
    Member since:
    Jan 2019

    Posted 17 Oct 2019 Link to this post

    Hi Guys,

    I can't make mine work using the example. Mine is slightly different on the hub with..

    public Kendo.DynamicLinq.DataSourceResult Read(KendoDataSourceRequest request, BookingTableParams data)

    I keep getting the error:

    "'read' method could not be resolved. No method found with that name."

     

    can you describe what individual changes had to be made to get this working?

     

    Thanks

  6. Don
    Don avatar
    11 posts
    Member since:
    Apr 2018

    Posted 18 Oct 2019 in reply to Stefan Link to this post

    Stefan,

    I realize your post is from Jan 2018 when you said you don't recommend using Kendo UI Grid with signalR when multiple users are working on the same grid. Since then, has there been any improvement from Kendo.UI for ASP.NET Core library to change your recommendation?

    I am currently trying to build an application and use SignalR on Kendo.UI grid asp.net core. Multiple users will collaborate on the same grid (ie. making data updates to specific rows) with up to 500 rows and data must be updated in real-time for all users. Each user must be able to use the filtering/sorting/paging features in Kendo UI Grid on their individual grid.

    Is this feasible with Kendo.UI Grid for asp.net core and SignalR ?

  7. Alex Hajigeorgieva
    Admin
    Alex Hajigeorgieva avatar
    1081 posts

    Posted 21 Oct 2019 Link to this post

    Hello, Don,

    The behaviour my colleague Stefan was referring to is proprietary to SignalR and not related with the Kendo UI Grid functionality. If you were using a table element to render the data on every push update, create and destroy, you would get the exact same behaviour.

    I believe that Stefan's point was to give you and others awareness that SignalR may not be a good idea if you expect constantly changing data and users trying to filter on it. Here is an example using the online demo and making it filterable + opening it in two different browsers:

    https://runner.telerik.io/fullscreen/@bubblemaster/oYumEfib

    • User A wants to see all the products with price over 200 
    • User B  goes and deletes this "Côte de Blaye" product which costs 263.5
    • The filter condition is no longer met and User A now has an empty grid

    If you feel that this is the correct technology for you and your circumstances and that the users will expect to get numerous updates and some of their records change or disappear whilst using the software, then the Kendo UI Grid will respond and render the latest data.

    I hope that this answers your question.

    Kind Regards,
    Alex Hajigeorgieva
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Back to Top