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

Grid entering two times in same read method call

6 Answers 1189 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Alberto
Top achievements
Rank 1
Alberto asked on 16 Dec 2019, 02:08 PM

I have a grid that when loading the data it is entering two times in ReadISHandler. I can see in debugger that enter and stops two times in LoadIS(); causing a performance problem, any idea what is happening

<TelerikGrid Data=@GridDataIS
             TotalCount=@Total
             Height=@Height
             ScrollMode="@GridScrollMode.Virtual"
             Sortable=false
             RowHeight="40" 
             OnRead=@ReadISHandler>

 

protected async Task ReadISHandler(GridReadEventArgs args)
        {
            Skip = args.Request.Skip;
            await LoadIS();
        }


6 Answers, 1 is accepted

Sort by
0
Marin Bratanov
Telerik team
answered on 16 Dec 2019, 02:15 PM

Hi Alberto,

Could you check if this is the situation that you hit: https://feedback.telerik.com/blazor/1442276-onread-called-twice-on-initialization? We are aware of such behavior during initialization and for the time being you can work around it through flags.

 

Regards,
Marin Bratanov
Progress Telerik

 UI for Blazor
0
Alberto
Top achievements
Rank 1
answered on 16 Dec 2019, 02:31 PM
yes looks like the same problem read is invoked two times.
0
Alberto
Top achievements
Rank 1
answered on 11 Jan 2020, 06:58 PM

do you have any sample code on how to avoid this with flags?

Will this be fixed in next versions as i see the issue approved but not planned to any version.

0
Marin Bratanov
Telerik team
answered on 13 Jan 2020, 06:02 AM

Hello Alberto,

I posted one workaround in the public page: https://feedback.telerik.com/blazor/1442276-onread-called-twice-on-initialization

You can click the Follow button there to get notified about status changes. It will be fixed, because it is a valid issue, even if I cannot say in which release that will happen.

Regards,
Marin Bratanov
Progress Telerik

 UI for Blazor
0
Jason
Top achievements
Rank 1
Iron
Veteran
answered on 04 Jun 2020, 02:56 PM
I'm stuck with this same issue trying to follow the sample code which definitely will not work. If you look at OnAfterRenderAsync, it has bool firstRender as a parameter so we can check for first render. It seems like OnRead should have that same parameter to work properly for Blazor Server. In the workaround, a counter is suggested, but this counter never gets reset so I'm not sure how that would work either.
0
Marin Bratanov
Telerik team
answered on 05 Jun 2020, 07:19 AM

Hi Jason,

In a server-side Blazor app this behavior is expected - the pre-rendering actually initializes all components twice - once on the server for the pre-rendering, and once the client-side portion of the app spins up. This is the case with all components, not just the grid. For example, if you fetch data in the OnInitialized event, it will be called twice too. For example, if you make a GET for the FetchData page from the default template, and modify it as follow,s you will find that statement twice in the console:

    protected override async Task OnInitializedAsync()
    {
        Console.WriteLine("fetching data");
        forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
    }

This behavior is expected and valid - for proper pre-rendering the components need to initialize and render, and for the grid that also means getting data.

If you want to reduce the calls, you must use some business logic to do that, for example, flag raised in the OnAfterRender event so you can call the OnRead handler yourself only then (a basic example of storing the grid request is available here: https://docs.telerik.com/blazor-ui/components/grid/manual-operations#cache-data-request). Here's another I made for you that uses a flag from OnAfterRender:

@using Telerik.DataSource

<TelerikGrid Data=@GridData TotalCount=@Total
             Pageable=true PageSize=15
             OnRead=@ReadItems>
    <GridColumns>
        <GridColumn Field=@nameof(Employee.Id) Title="ID" />
        <GridColumn Field=@nameof(Employee.Name) Title="Name" />
    </GridColumns>
</TelerikGrid>

@code {
    public List<Employee> GridData { get; set; }
    public int Total { get; set; } = 0;
    bool hasComponentRenderedOnce { get; set; }
    DataSourceRequest CurrentRequest { get; set; }

    protected async Task ReadItems(GridReadEventArgs args)
    {
        CurrentRequest = args.Request;
        if (hasComponentRenderedOnce)
        {
            await FetchData();
        }
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            hasComponentRenderedOnce = true;
            FetchData();
        }
    }

    async Task FetchData()
    {
        if (CurrentRequest == null)
        {
            return;
        }

        Console.WriteLine("ReadItems"); // fetch actual data here and populate Total and GridData
    }


    public class Employee
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

Regards,
Marin Bratanov
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
Paul Wood
Top achievements
Rank 1
commented on 09 Nov 2021, 02:21 AM

If you don't want to use OnRead and are using the simpler
protected override async Task OnInitializedAsync()
{
	await LoadData();
}
are there any issues with just replacing the above with the following instead to avoid the two calls to the database?:
protected override async Task OnAfterRenderAsync(bool firstRender)
{
	if (firstRender)
	{
		await LoadData();
		StateHasChanged();
	}
Marin Bratanov
Telerik team
commented on 09 Nov 2021, 07:17 PM

That's the typical approach people tend to take in such cases.

I would only suggest you call
await InvokeAsync(StateHasChanged);
so that you are sure it executes in the main thread.

Tags
Grid
Asked by
Alberto
Top achievements
Rank 1
Answers by
Marin Bratanov
Telerik team
Alberto
Top achievements
Rank 1
Jason
Top achievements
Rank 1
Iron
Veteran
Share this question
or