Observable Grid does not update upon a changes with the dataset

Hello. I'm having trouble with a specific observable data collection. For some reason, when data is changed, the grid fails to update. Interestingly, when data is added or removed, the data is properly updated.  Weirdest thing is that this was working perfectly until this week. Can't figure out why for the life of me. Thanks. 


[code for FetchDataObv page]
@page "/fetchDataObv"
@using Syncfusion.Blazor.Grids
@using Syncfusion.Blazor
@using Syncfusion.Blazor.Buttons
@using PowerBlazor.Data
@using System.Dynamic
@using System.Collections.ObjectModel
@using System.ComponentModel
@using System.Security.Cryptography.X509Certificates
@using System.Threading
@using Syncfusion.Blazor.Charts.BulletChart.Internal
@using Syncfusion.Blazor.PivotView.Internal
@using SelectionType = Syncfusion.Blazor.Grids.SelectionType
@inject Data.WeatherForecastService _foreCastService
@inject IJSRuntime JSRuntime
@*needed to run the JS runtime obviously>*@ 


<div class="heading">
    <h1>Weather forecast</h1>
    <p>This component demonstrates fetching data from the server.</p>
</div>

@if (GridData == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <input type="text" @bind="temperatureCelEdit" />
    <input type="text" @bind="summaryEdit" />
    <SfButton ID="add" @onclick="AddData">Add Data</SfButton>
    <SfButton ID="del" @onclick="DeleteData">Delete Data</SfButton>
    <SfButton ID="update" @onclick="ChangeData">Update Data</SfButton>
    <SfGrid @ref="gridReference" AllowSelection="true" DataSource="@GridData" AllowPaging="true" AllowSorting="true">
        <!--Allow paging puts data in pages--->
        <!--Allow sorting allows for.... sorting--->
        <!--Filtering allows user to search within the table, customizing this say to only apply to a specific field requires a seperate function. See documentation.--->
        <!--Grouping allows user to drag and drop the table/remove items--->
        <GridPageSettings PageSize="20"></GridPageSettings>
        <GridEditSettings AllowAdding="true" AllowDeleting="true"></GridEditSettings>
        <GridSelectionSettings Type="SelectionType.Multiple"></GridSelectionSettings> <!---Selection type multiple allows you to select multiple grids-->
        <GridEvents QueryCellInfo="CellInfoHandler" TValue="WeatherForecast"></GridEvents>
        <GridColumns>
            <!--Notice the nameof field refers to the class within the data set, not the data set itself--->
            <GridColumn Field=@nameof(WeatherForecast.Date) HeaderText="Custom Date" AllowSorting="true"></GridColumn> <!--HeaderText allows for custom fields, if left empty these will be autofilled based on the variables in the class--->
            <GridColumn Field=@nameof(WeatherForecast.TemperatureC)  HeaderText="Custom Temp C"></GridColumn>
            <GridColumn Field=@nameof(WeatherForecast.TemperatureF) Format="N2" HeaderText="Custom Temp F"></GridColumn>
            <GridColumn Field=@nameof(WeatherForecast.Summary) HeaderText="Custom Summary"></GridColumn>
            <GridColumn Field=@nameof(WeatherForecast.lastUpated) HeaderText="Custom Summary"></GridColumn>
        
        </GridColumns>
    </SfGrid>
    <style>
        .below{
            background-color: #5c92f7;
        }

        .above{
            background-color: #e3b024;
        }
    </style>

}

@code {

    public SfGrid<WeatherForecast> gridReference;

    private Timer aTimer;

    private Random rng = new Random();

    public ObservableCollection<Data.WeatherForecast> GridData { get; set; }

    private int temperatureCelEdit { get; set; }
    private string summaryEdit { get; set; }


    public void AddData()
    {
        GridData.Add(new WeatherForecast() { Date = DateTime.Now, TemperatureC = temperatureCelEdit, Summary = summaryEdit, });
    }

    public void DeleteData()
    {
        GridData.Remove(GridData.First());

    }

    public void ChangeData()
    {
        @*Test to change data *@
    var currentSet = GridData.First();
}


    protected override async void OnInitialized()
    {
        var data = await _foreCastService.GetForecastAsync(DateTime.Now);
        GridData = new ObservableCollection<WeatherForecast>(data);


        aTimer = new Timer(
            delegate (object state)
            {
                UpdateRandomRow();
            },
            null,
            TimeSpan.Zero,
            TimeSpan.FromSeconds(.5)
            );

    }

    private async void unSelect(int idx) //async functions for the delay
    {
        await Task.Delay(1000);


        await JSRuntime.InvokeAsync<object>("unApplycolor", idx); // runs JS file



    }

    private void UpdateRandomRow()
    {
        // 1. Pick a random row.


        var idx = new Random().Next(0, GridData.Count);

        // 2. Update its value randomly.
        var row = GridData[idx];
        row.TemperatureC = rng.Next(-20, 55);
        row.lastUpated = DateTime.Now;
        idx = idx - ((gridReference.PageSettings.CurrentPage - 1) * gridReference.PageSettings.PageSize); //only required for paging, needed to adjust index to page

        //runs JS to change color
        JSRuntime.InvokeAsync<object>("applycolor", idx);

        unSelect(idx);


    }

    public void CellInfoHandler(QueryCellInfoEventArgs<WeatherForecast> Args)
    {
        if (Args.Column.Field == "TemperatureC")
        {
            if (Args.Data.TemperatureC < 0)
            {
                Args.Cell.AddClass(new string[] {"below"});

            }
            else
            {
                Args.Cell.AddClass(new string[] { "above" });

            }

        }
    }


}



[weatherForecast class]

using System;
using System.ComponentModel;
using System.Dynamic;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Threading.Tasks;
using System.Threading;


namespace PowerBlazor.Data
{
    public class WeatherForecast : INotifyPropertyChanged
    {

        
        public DateTime Date { get; set; }

        public DateTime lastUpated { get; set; } //last updated event


        public int TemperatureC { get; set; }


        public float TemperatureF => 32 + (TemperatureC / 0.5556f);

        public string Summary { get; set; }
        

        /*private static int newTemps()
        {
            //takes up space so this should probably be moved to an external function or just edit C and F directly

            Random rng = new Random();

            return rng.Next(-20, 55);

        }*/

        

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    }







}


I have a class that generates the WeatherForecast objects, and it hasn't been changed since last week.


5 Replies

VN Vignesh Natarajan Syncfusion Team May 25, 2021 05:35 AM UTC

Hi Simon,  
 
Thanks for contacting Syncfusion support.  
 
Query: “For some reason, when data is changed, the grid fails to update. 
 
We have analyzed your query and we are able to reproduce the reported issue at our end also while using your code example. For observable collection, properties needs to configured with NotifyPropertyChanged event handler to reflect the changes directly in Grid. We have modified your sample to update the changes in Grid.  
 
Refer the below code example.  
 
public class WeatherForecast : INotifyPropertyChanged 
    { 
        public DateTime Date { getset; } 
        public DateTime lastUpated { getset; } //last updated event 
        public int TemperatureC { getset; } 
        public float TemperatureF => 32 + (TemperatureC / 0.5556f); 
        public string Summary 
        { 
            get { return summary; } 
            set 
            { 
                summary = value; 
                NotifyPropertyChanged("Summary"); 
            } 
        } 
        private string summary { getset; } 
        public event PropertyChangedEventHandler PropertyChanged; 
        private void NotifyPropertyChanged(string propertyName)        { 
            var handler = PropertyChanged; 
            if (handler != null) 
            { 
                handler(thisnew PropertyChangedEventArgs(propertyName)); 
            } 
        } 
    } 
 
 
For your convenience we have prepared a sample which can be downloaded from below  
 
 
Refer our online demo for your reference 
 
 
Please get back to us if you have further queries.  
 
Regards, 
Vignesh Natarajan 



SS Simon Sandrew May 25, 2021 01:10 PM UTC

Hi Vignesh,

Unfortunately, making this change does not result in an update in the table. While data within the dataset is being changed(I can tell through my debugger) the data is not being refreshed properly. Since I originally posted, I've found out that when data is deleted or added, the grid refreshes, but not upon a data change. It seems that it is only when the count is changed that the data is updated automatically. Let me know if there is still anything I can fix on my own end. Thanks.


VN Vignesh Natarajan Syncfusion Team May 26, 2021 06:52 AM UTC

Hi Simon,  
 
Query: “Unfortunately, making this change does not result in an update in the table 
 
We are not able to reproduce the reported issue at our end. So we need some more details about the issue you are facing. Kindly share the following details.  
 
  1. Are you facing issue when trying to update the column value on a timer?
  2. Are you facing the reported issue in modified sample provided by us (in previous update)?
  3. Share the video demonstration of the issue along with replication procedure.  
  4. Confirm your Syncfusion Nuget packages version details.
  5. If possible share the issue reproducible sample or try to reproduce the reported issue in provided sample.
 
Above requested details will be very helpful for us to validate the reported query at our end and provide solution as early as possible.  
 
Regards, 
Vignesh Natarajan 



SG Sven G May 29, 2024 01:21 PM UTC

I had the same issue,


I can confirm it is working when implementing INotifyPropertyChanged.

This is something you have to implement besides using ObservableCollection, though.




PS Prathap Senthil Syncfusion Team May 31, 2024 01:03 AM UTC

Hi Sven


We are happy to hear that the provided solution was helpful in resolving your problem. We would also like to clarify that for an observable collection, properties need to be configured with the NotifyPropertyChanged event handler to reflect the changes directly in the Grid. Thanks for your understanding.



Regards,

Prathap Senthil


Loader.
Up arrow icon