This is a migrated thread and some comments may be shown as answers.

Add item (SignalR) to filtered/grouped GridDataResult

4 Answers 54 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Michael
Top achievements
Rank 1
Veteran
Iron
Michael asked on 03 Oct 2019, 07:37 AM

Hi!

I have a grid where data are loaded with a service from a web api.

<kendo-grid [data]="logs"
                    [pageSize]="state.take"
                    [skip]="state.skip"
                    [sort]="state.sort"
                    [sortable]="{
                        allowUnsort: true,
                        mode: 'multiple'
                    }"
                    [pageable]="true"
                    [groupable]="true"
                    [group]="state.group"
                    [columnMenu]="false"
                    [filterable]="'menu'"
                    [filter]="state.filter"
                    (filterChange)="filterChange($event)"
                    [resizable]="true"
                    (dataStateChange)="dataStateChange($event)"></kendo-grid>

 

This is the fetch method to query the data (logs):

public fetchLogs(state: DataSourceRequestState): Observable<any>
    {
        const queryStr = `${toDataSourceRequestString(state)}`;
        const hasGroups = state.group && state.group.length;
 
        return this.http
            // Send the state to the server
            .get(`${this.apiUrl}/log?${queryStr}`)
            .pipe(
                // Process the response
                map(({ data, total }: GridDataResult): GridDataResult =>
                {
                    const newData = hasGroups ? translateDataSourceResultGroups(data) : data;
                    return {
                        data: newData,
                        total: total
                    };
                }),
                map(res =>
                {
                    res.data.map(item =>
                    {
                        item.logZeit = new Date(item.logZeit);
                        return item;
                    })
                    return res;
                })
            );
    }

 

At the same time, the data are updated via signalR - like this:

logHubService.logCreated.subscribe(log =>
        {
            log.logZeit = new Date(log.logZeit);
            this.logs.data = [log, ...this.logs.data];
            this.logs.total += 1;
 
        });
        logHubService.logUpdated.subscribe(log =>
        {
            const logData = this.logs.data as ILog[];
            let updateableLog = logData.filter(x => x.id === log.id);
            if (updateableLog.length == 1)
            {
                updateableLog[0].logLevel = log.logLevel;
                updateableLog[0].logLevelId = log.logLevelId;
                updateableLog[0].logTyp = log.logTyp;
                updateableLog[0].logTypId = log.logTypId;
                updateableLog[0].logZeit = new Date(log.logZeit);
                updateableLog[0].text = log.text;
            }
        });
        logHubService.logDeleted.subscribe(log =>
        {
            this.logs.data = this.logs.data.filter(x => x.id !== log.id);
            this.logs.total -= 1;
        });

 

But i have troubles when grid is filtered/grouped because the structure of this.logs.data has changed.

Can you give me a hint to solve this problem?

 

 

 

 

 

4 Answers, 1 is accepted

Sort by
0
Dimiter Topalov
Telerik team
answered on 07 Oct 2019, 08:03 AM

Hi Michael,

When the Grid data is grouped, it is structured as a collection of GroupResult objects:

https://www.telerik.com/kendo-angular-ui/components/grid/grouping/

https://www.telerik.com/kendo-angular-ui/components/dataquery/api/GroupResult/

From the provided code it seems that the data operations like paging, sorting, filtering, and grouping are performed on the server, thus the most straight-forward approach to include CRUD operations in the mix, would be to send the created/updated/deleted item to the server, update the whole collection there accordingly, and process the updated collection in accordance with the current Grid state.

This way the data service will read the latest processed items from the server where the CRUD change was persisted as per the paragraph above, and the Grid will be rerendered accordingly.

I hope this helps.

Regards,
Dimiter Topalov
Progress Telerik

Get quickly onboarded and successful with your Telerik and Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Michael
Top achievements
Rank 1
Veteran
Iron
answered on 20 Feb 2020, 01:39 PM

Hi Dimiter,

thx for your reply and apologize my long absence.

Is there no way to get a specific item from 'GridDataResult' when the data are grouped?

I don't want to load the data again because I have already transferred the updated object to the client!

 
 
0
Dimiter Topalov
Telerik team
answered on 24 Feb 2020, 08:56 AM

Hi Michael,

I am not sure I fully understand the question and the scenario. The developer can traverse the grouped data structure (an array of arrays basically, where all groups have the specific data items under the given group under its 'items' property).

However when the built-in Grid editing functionality is used, each time the developer edits or removes an existing item, it is available in the context of the editing-related events:

https://www.telerik.com/kendo-angular-ui/components/grid/editing/editing-reactive-forms/

https://www.telerik.com/kendo-angular-ui/components/grid/api/EditEvent/ // the dataItem property

When the end user adds an item, the item is created based on the FormGroup object configured by the developer:

https://www.telerik.com/kendo-angular-ui/components/grid/editing/editing-reactive-forms/#toc-adding-records

Then the newly created item can be created based on the FormGroup's value, and will be available as "dataItem" in the "add" event handler and when saving the new item in the "save" event handler:

https://www.telerik.com/kendo-angular-ui/components/grid/api/AddEvent/

https://www.telerik.com/kendo-angular-ui/components/grid/editing/editing-reactive-forms/#toc-saving-records

https://www.telerik.com/kendo-angular-ui/components/grid/api/SaveEvent/

Then the developer can either send the added/updated item to the server and persist it in the database immediately, or implement some kind of batch editing service on the client that will store all changes locally, and then send them to the server in one go when desired like in the following example:

https://www.telerik.com/kendo-angular-ui/components/grid/editing/in-cell-editing/

This way communication with the server can be limited as necessary.

Another option is to send the new item to the server, and upon receiving an OK response indicating the item is received and stored on the server, update the local collection without reading the whole data set from the server again. The exact workflow will heavily depend on the use case and the scenario requirements.

If multiple end users will update the same data set and should see the same Grid data at all times, then it will be perhaps be best to sync the local data each time the data on the server is changed. If this is not the case, all local changes can be stored in a local data service, and then synced with the server when a special "Save changes" or similar action is triggered.

I hope this helps, but if I am missing something, can you please describe the scenario and the desired behavior and functionality in further details, so I can try to provide a solution that is best suitable for the specific use case? Thank you in advance.

Regards,
Dimiter Topalov
Progress Telerik

Get quickly onboarded and successful with your Telerik and Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Michael
Top achievements
Rank 1
Veteran
Iron
answered on 25 Feb 2020, 07:44 AM

Hi!

Thank you for your detailed explanation!

I thought maybe there is already a built-in solution to get all data elements in a grouped state!

Now I have the following solution - maybe it helps somebody:

export function fetchItemsFromGridDataResult(data: any[]): any[]
{
    return [].concat.apply([], (data.map(item =>
    {
        if (isGroupResult(item))
            return fetchItemsFromGridDataResult((item as GroupResult).items);
        return item;
    })));
}
 
 
Tags
Grid
Asked by
Michael
Top achievements
Rank 1
Veteran
Iron
Answers by
Dimiter Topalov
Telerik team
Michael
Top achievements
Rank 1
Veteran
Iron
Share this question
or