I am working on a server side Blazor application. My goal is to dynamically populate a dropdown with a list of objects, then do something with that object when it is selected. This is the error I am getting:
The call is ambiguous between the following methods or properties: 'RenderTreeBuilder.AddAttribute(int, string, string?)' and 'RenderTreeBuilder.AddAttribute(int, string, MulticastDelegate?)'
The error is in the file "ListDropdownComponent.g.cs" I have not made any changes to this file, so I suspect Visual Studio is pointing me to the wrong source.
When I comment out this bit of code the error goes away, so I think this is where the error is:
<InputSelect @bind-Value="SelectedList" TValue="ListModel" @onchange="AddToList">
<option value="@null">Add to list</option>
@foreach (ListModel list in Lists)
{
<option value="@list">@list.ListName</option>
}
<option value="@(new ListModel{ ListID = -1, ListName="New List" }) ">New List</option>
</InputSelect>
SelectedList is using the ListModel class:
public ListModel SelectedList;
UPDATE: I switched to using the int ID property of my class and I am still getting the same error. So I have no idea what the cause is.
UPDATE 2: This is the problem: value="@null". I will find a way to work around this, but since int? is nullable I would still like to know what the actual issue is.
CodePudding user response:
For one, html attributes cannot have null values, this is described in the docs here:
HTML attributes can't have null values. The closest equivalent to null in HTML is absence of the HTML value attribute from the element.
When selecting an
<option>
with no value attribute, the browser treats the value as the text content of that<option>
's element.
Having said that, I don't see why Blazor shouldn't be able to handle this case for you. In fact, there is an issue posted about that here. So, I guess the current answer would be Currently Blazor does not support this use case
.
The workaround for this is to use an empty string ""
and do the conversion between null
yourself.
CodePudding user response:
Your fundamental problem is here:
<option value="@list">@list.ListName</option>
where list
is an object. If you check what you produce in the browser Dev tools it will look something like this:
<select>
<option value="BlazorApp4.Pages.Index ListModel">French</option>
<option value="BlazorApp4.Pages.Index ListModel">Spanish</option>
<option value="BlazorApp4.Pages.Index ListModel ">New List</option>
</select>
value
in an option
must be a string.
You need to rethink how you code this. Without more context I'd be shooting in the dark making suggestions.
CodePudding user response:
You're doing it wrong. Here's one way to do that:
<InputSelect ValueExpression="@(() => selectedList.ListID)" Value="@selectedList.ListID" ValueChanged ="@(()=>AddToList(args))">
<option value="">Select list...</option>
@foreach (ListModel list in Lists)
{
<option @key="ListModel" value="@list.ListID">@list.ListName</option>
}
</InputSelect>
@code
{
private selectedList ListModel = new ListModel();
private void AddToList(int? args)
{
selectedList.ListID = args;
}
}
Note: I did not run this code. If you get an error let me know.
The issue that you use the @onchange
directive with the InputSelect component. You shouldn't use it that way. Don't use the @onchange
directive with components. You can't use it that way because the @bind-Value
directive already use the @onchange
directive internally. Thus the ambiguity.