Skip to content

PDTable does not reload when given a different DataProvider instance #147

Description

@davidnmbond

Summary

PDTable fetches from its DataProvider only once, in OnAfterRenderAsync(firstRender) when AutoLoad is true. If the parent later supplies a different DataProvider instance to the same PDTable, nothing reloads: the table keeps rendering the rows it loaded from the previous provider until the component is recreated (for example by a full page reload).

Why it matters

This is easy to hit without noticing. Any parent that renders a PDTable inside a list, and builds a provider per item, gets its PDTable instances reused positionally by Blazor's diff when the list changes. Each reused table is handed its new provider and silently keeps showing the old data. Nothing throws, and the surrounding markup (headings, counts) updates correctly, so the page presents one item's rows under another item's heading.

Reproduction

  1. Render <PDTable TItem="Row" DataProvider="@_provider" AutoLoad="true"> with _provider returning rows A, B.
  2. After it has loaded, set _provider to a new instance returning rows C, D, E and re-render the parent.
  3. Expected: the table shows C, D, E.
  4. Actual: the table still shows A, B.

A bUnit test shows it directly: render with provider 1, wait for its rows, call cut.Render(p => p.Add(x => x.DataProvider, provider2)), and the rendered rows are still provider 1's.

Workaround in use

The consumer tracks the provider it last loaded, and when the parameter changes to a different instance it calls RefreshAsync() in OnAfterRenderAsync, followed by StateHasChanged(). The StateHasChanged() is needed too: RefreshAsync() refetches but does not re-render the table (the first-render path calls StateHasChanged() explicitly for the same reason).

Suggested fix

In PDTable.OnParametersSet (or SetParametersAsync), detect that DataProvider has changed by reference after the first load and schedule a reload after the next render, resetting paging to the first page. It would also be worth considering whether RefreshAsync() should call StateHasChanged() itself, since a caller that refreshes from outside the render cycle otherwise sees nothing change.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions