Update issue with dropdownlist and an ObservableCollection datasource with Async
Hi,
If the datasource for a dropdownlist is an Async ObservableCollection then inserts and deletes to the ObservableCollection do not update the dropdown.
Remove the Task from the creation of the ObservableCollection then the dropdownlist correctly updates.
protected override async Task OnInitializedAsync()
{
// Get list of dashboards to bind to the dropdown
//this.DashBoards = new ObservableCollection<DashBoard>(await this.DashBoardRepositoryObj.GetDashBoardsAsync());
this.DashBoards = await Task.Run(() => new ObservableCollection<DashBoard>(new List<DashBoard>() {
new DashBoard { DashBoardId = 0, Name = "Bob" },
new DashBoard { DashBoardId = 1, Name = "Mike" },
new DashBoard { DashBoardId = 2, Name = "Glenn" },
new DashBoard { DashBoardId = 3, Name = "Guy" },
new DashBoard { DashBoardId = 4, Name = "Johnny" },
new DashBoard { DashBoardId = 5, Name = "Nick" } }));
}
SIGN IN To post a reply.
16 Replies
1 reply marked as answer
SP
Sureshkumar P
Syncfusion Team
October 30, 2020 02:14 AM UTC
Hi Michael,
Greetings from Syncfusion support.
Based on your shared information with code example. We have created the sample and we cannot able to replicate the reported issue from our end.
Please find the code example here:
|
<SfDropDownList @ref="ddl1" TValue="int?" Index="IndexVal" TItem="SpareNameViewModel" @bind-Value="@DDLValue" DataSource="@customData">
<DropDownListFieldSettings Text="Name" Value="Code"></DropDownListFieldSettings>
</SfDropDownList>
@code {
SfDropDownList<int?, SpareNameViewModel> genericCustomerPicker;
public IEnumerable<SpareNameViewModel> DataSource { get; set; }
public int? CustomCustDropValue
{
get; set;
}
SfDropDownList<int?, SpareNameViewModel> ddl1;
public ObservableCollection<SpareNameViewModel> customData { get; set; }
public int? DDLValue { get; set; }
public int? IndexVal { get; set; } = null;
protected override async Task OnInitializedAsync()
{
customData = await ForecastService.GetSpareNamesAsync();
this.StateHasChanged();
this.DDLValue = await ForecastService.GetSpareNamesValueAsync(); // Change Value
// add the datasource dynamically using addItems method
this.customData.Insert(0, new SpareNameViewModel() { Name = "Bob", Id = 10 });
}
}
|
Please find the screen shot here:
|
|
Please find the sample here: https://www.syncfusion.com/downloads/support/directtrac/general/ze/AsyncDDDLInsertMethod-702468700
If still you have facing the issue, then please replicate the reported issue from above attached sample and revert us with detailed issue replication steps. That will help us to provide exact solution as earlier as possible.
Regards,
Sureshkumar P
MA
Michael Aston
November 13, 2020 11:26 AM UTC
Hi,
Hopefully the following code will demo the issue.
The Add and Remove will update the dropdown when the ObservableCollection is created in OnInitialized. If you comment out OnInitialized and uncomment OnInitializedAsync so the ObservableCollection is created in the Async, then the Add and Remove do not update the dropdown.
Regards,
Mike
@page "/"
@using Syncfusion.Blazor.DropDowns;
@using Syncfusion.Blazor.Buttons;
@using System.Collections.Generic;
@using System.Collections.ObjectModel;
<SfDropDownList Width="250px" DataSource=@DashBoards TValue=int? TItem=@DashBoard @bind-Value=@DashBoardId @ref=ddlDashBoards>
<DropDownListFieldSettings Value=@nameof(DashBoard.DashBoardId) Text=@nameof(DashBoard.Name) />
</SfDropDownList>
<SfButton OnClick=@Add>Add Fred</SfButton>
<SfButton OnClick=@Delete>Delete Mike</SfButton>
@code {
public class DashBoard
{
public DashBoard() { }
public int DashBoardId { get; set; }
public string Name { get; set; }
}
SfDropDownList<int?, DashBoard> ddlDashBoards;
protected int? DashBoardId { get; set; } = 1;
protected ObservableCollection<DashBoard> DashBoards { get; set; }
//protected override async Task OnInitializedAsync()
//{
// this.DashBoards = await Task.Run(() => new ObservableCollection<DashBoard>(new List<DashBoard>() {
// new DashBoard { DashBoardId = 0, Name = "Bob" },
// new DashBoard { DashBoardId = 1, Name = "Mike" },
// new DashBoard { DashBoardId = 2, Name = "Glenn" },
// new DashBoard { DashBoardId = 3, Name = "Guy" },
// new DashBoard { DashBoardId = 4, Name = "Johnny" },
// new DashBoard { DashBoardId = 5, Name = "Nick" } }));
//}
protected override void OnInitialized()
{
this.DashBoards = new ObservableCollection<DashBoard>(new List<DashBoard>() {
new DashBoard { DashBoardId = 0, Name = "Bob" },
new DashBoard { DashBoardId = 1, Name = "Mike" },
new DashBoard { DashBoardId = 2, Name = "Glenn" },
new DashBoard { DashBoardId = 3, Name = "Guy" },
new DashBoard { DashBoardId = 4, Name = "Johnny" },
new DashBoard { DashBoardId = 5, Name = "Nick" } });
}
protected void Add()
{
this.DashBoards.Add(new DashBoard() { DashBoardId = 6, Name = "Fred" });
}
protected void Delete()
{
DashBoard DashBoardObj = this.DashBoards.Where(x => x.DashBoardId == 1).First<DashBoard>();
this.DashBoards.Remove(DashBoardObj);
}
}
BC
Berly Christopher
Syncfusion Team
November 18, 2020 11:31 AM UTC
Hi Michael,
Thanks for providing information.
We can add and remove the item to the DropDownList component while assigning the data source asynchronously by implement INotifyPropertyChanged to the model class of DropDownList. In the below example, DashBoard class implements the INotifyPropertyChanged and it raises the event when the value gets changed.
|
<SfDropDownList Width="250px" DataSource=@DashBoards TValue=int? TItem=@DashBoard @bind-Value=@DashBoardId @ref=ddlDashBoards>
<DropDownListFieldSettings Value=@nameof(DashBoard.DashBoardId) Text=@nameof(DashBoard.Name) />
</SfDropDownList>
<SfButton OnClick=@Add>Add Fred</SfButton>
<SfButton OnClick=@Delete>Delete Mike</SfButton>
@code {
public class DashBoard : INotifyPropertyChanged
{
public DashBoard() { }
public string Name { get; set; }
public int DashBoardId
{
get { return _DashBoardId; }
set
{
_DashBoardId = value;
NotifyPropertyChanged("DashBoardId");
}
}
public int _DashBoardId { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
SfDropDownList<int?, DashBoard> ddlDashBoards;
protected int? DashBoardId { get; set; } = 1;
protected ObservableCollection<DashBoard> DashBoards { get; set; }
protected override async Task OnInitializedAsync()
{
this.DashBoards = new ObservableCollection<DashBoard>(new List<DashBoard>() {
new DashBoard { DashBoardId = 0, Name = "Bob" },
new DashBoard { DashBoardId = 1, Name = "Mike" },
new DashBoard { DashBoardId = 2, Name = "Glenn" },
new DashBoard { DashBoardId = 3, Name = "Guy" },
new DashBoard { DashBoardId = 4, Name = "Johnny" },
new DashBoard { DashBoardId = 5, Name = "Nick" } });
}
protected async Task Add()
{
this.DashBoards.Add(new DashBoard() { DashBoardId = 6, Name = "Fred" });
}
protected async Task Delete()
{
DashBoard DashBoardObj = this.DashBoards.Where(x => x.DashBoardId == 1).First<DashBoard>();
this.DashBoards.Remove(DashBoardObj);
}
public async Task<DashBoard> updateDate()
{
var data = new DashBoard() { DashBoardId = 6, Name = "Fred" };
return await Task.FromResult(data);
}
} |
Please find the modified sample from the below link.
Sample Link: https://www.syncfusion.com/downloads/support/directtrac/general/ze/DropDownDataSource-1305292217
Regards,
Berly B.C
MA
Michael Aston
November 18, 2020 03:02 PM UTC
Hi,
Your sample has missed the await on the creation of the collection. If you add this back in then it fails again.
Wouldn't a better approach be to drop the use of the ObservableCollection due its issues with async/threading and use a List and expose a StateHasChanged/CollectionHasChanged method on the dropdown that can be called to notify of an update to the collection.
Regards,
Mike
BC
Berly Christopher
Syncfusion Team
November 19, 2020 02:23 PM UTC
Hi Michael,
We will check the reported issue and provide the further details in two business days (23rd November 2020). We appreciate your patience until then.
Regards,
Berly B.C
BC
Berly Christopher
Syncfusion Team
November 20, 2020 02:17 PM UTC
Hi Michael,
Thanks for the patience.
We would like to inform you that, when you are assigning the observable collection in the async method with await function, we suggest you to assign the values in the separate async method as mentioned below code snippet to get rid of the reported issue.
|
protected override async Task OnInitializedAsync()
{
this.DashBoards = await GetItemsAsync();
}
public async Task<ObservableCollection<DashBoard>> GetItemsAsync()
{
return new ObservableCollection<DashBoard>() {
new DashBoard { DashBoardId = 0, Name = "Bob" },
new DashBoard { DashBoardId = 1, Name = "Mike" },
new DashBoard { DashBoardId = 2, Name = "Glenn" },
new DashBoard { DashBoardId = 3, Name = "Guy" },
new DashBoard { DashBoardId = 4, Name = "Johnny" },
new DashBoard { DashBoardId = 5, Name = "Nick" } };
} |
Modified sample Link: https://www.syncfusion.com/downloads/support/directtrac/general/ze/DropDownDataSource_159191675417127
Regards,
Berly B.C
MA
Michael Aston
November 21, 2020 01:08 PM UTC
Hi,
As you've not awaited the creation of the observable collection in GetItemAsync() the call will be synchronous rather than asynchronous, so its like it's called from OnInitialized rather than OnInitializedAsync again.
The core problem here is that the creation of the observable collection and the add/removes to it must be on the same thread. I can't see how an observable collection will work with the threading model of Blazor server, which I'm using.
You either need another method to notify the dropdown of a change to the collection or you need to use an implementation of an observable collection that forces access to the collection to be on the same thread as the creation of the collection.
Regards,
Mike
MA
Michael Aston
November 26, 2020 10:52 AM UTC
Hi,
Anything happening on this?
Regards,
Mike
SN
Sevvandhi Nagulan
Syncfusion Team
November 29, 2020 12:53 PM UTC
Hi Michael,
Sorry for the inconvenience caused.
We are validating the reported requirement. We will update further details on 1st December,2020. We appreciate your patience until then.
Regards,
Sevvandhi N
BC
Berly Christopher
Syncfusion Team
December 7, 2020 07:53 AM UTC
Hi Michael,
Thanks for the patience.
We have confirmed the reported issue as a bug at our end and this fix will be included in our Volume 4 Main release which is expected to be rolled out on end of December 2020. We appreciate your patience until then.
Please track the status of the issue from the below feedback link.
Regards,
Berly B.C
MA
Michael Aston
January 4, 2021 10:46 AM UTC
Can you tell me if a fix for this was implemented in Vol4 as scheduled?
BC
Berly Christopher
Syncfusion Team
January 5, 2021 10:43 AM UTC
Hi Michael,
Thanks for the patience.
We are glad to announce that our release in the version 18.4.30 has been rolled out successfully and in that release, we have included the “Add and remove is not working while creating the data source as observable collection in async await function”. So, we suggest you upgrade our Syncfusion packages to our latest version to resolve this issue in your end.
Release notes: https://blazor.syncfusion.com/documentation/release-notes/18.4.30/?type=all#dropdownlist
Regards,
Berly B.C
CG
Coder Gal
August 4, 2021 11:21 PM UTC
This is still an issue in Syncfusion.Blazor 19.1.0.63
BC
Berly Christopher
Syncfusion Team
August 5, 2021 10:20 AM UTC
Hi Coder Gal,
Greetings from Syncfusion support.
We have checked the sample in the 19.1.0.63 version and the reported issue is does not occurred at our end. We have taken video demonstration and attached it below.
Video Link: https://www.syncfusion.com/downloads/support/directtrac/general/ze/Additem_159191-1947843527
Sample Link: https://www.syncfusion.com/downloads/support/directtrac/general/ze/DropDownDataSource1710220307
Still issue persists, please share the issue reproducing sample or modify the attached sample with reported issue that will help us to check and proceed further from our end.
Regards,
Berly B.C
Marked as answer
CG
Coder Gal
August 5, 2021 05:35 PM UTC
Thank you for reply. You are correct: it works in your solution.
One difference between your solution and what I have is that my solution targets net5.0 standard.
The solution you've provided targets netstandard2.1
When I create a blank Blazor WASM solution targeting .net5.0 (not netstandard2.1), and try to implement the code, the control does not load Dashboards list. It returns "no records found"
Also, dropdown part of the control is not positioned correctly (its position is distorted)
BC
Berly Christopher
Syncfusion Team
August 6, 2021 06:20 AM UTC
Hi Coder Gal,
We were able to reproduce the reported issue at our end and this issue has been resolved in our 19.2.0.44 version. So, we suggest you to upgrade the Syncfusion NuGet to the 19.2.0.44 or latest version 19.2.0.51 version to get rid of the reported issue.
For your convenience, we have prepared the sample and attached it below.
Sample Link: https://www.syncfusion.com/downloads/support/directtrac/general/ze/Blazor_WASM_1591911312961576
Regards,
Berly B.C
SIGN IN To post a reply.
- 16 Replies
- 5 Participants
- Marked answer
-
MA Michael Aston
- Oct 28, 2020 10:57 PM UTC
- Aug 6, 2021 06:20 AM UTC