Blazor passing columnname parameter to component and second parameter in component

69 views Asked by At

So I have a div, in this div there is a Sort Component. What I want to achieve is, when I click on one of the icons from Component, it should call LoadProjects with following parameters: columnname and isAscending. It depends on the icon which is clicked, whether isAscending should be true or false. I will provide some screenshots of my code. I kinda coded it with the help of ChatGPT but I get an error.

[Table.razor file:]

<th class="M2 border-color">
    <div class="flex ml-[25px] flex-row text">
        <span>release</span>
        <Sort columnName="projectname" OnSortClick="LoadProjects"/>
        <Filter />
    </div>
</th>

[LoadProjects Method in Table.razor]

private async Task LoadProjects(string column, bool asc)
{
    projects = await projectsService.GetProjects(column, asc);
    sortedProjects = new List<Projects>(projects);
}

[Sort Component]

<svg class="ml-[10px]" xmlns="http://www.w3.org/2000/svg" width="16" height="20" viewBox="0 0 16 20" fill="none">
    <path d="M8 0L14.4952 7.5H1.50481L8 0Z" fill="#C0C5CA" @onclick="HandleClickAsc" />
    <path d="M2.59926 13L8 19.2362L13.4007 13H2.59926Z" fill="#C0C5CA" stroke="#C0C5CA" @onclick="HandleClickDesc"/>
</svg>

@code{
 [Parameter] public string columnName { get; set; }
 [Parameter] public EventCallback<(string, bool)> OnSortClick { get; set; }

    private async Task HandleClickAsc()
    {
        await OnSortClick.InvokeAsync((columnName,false));
    }

    private async Task HandleClickDesc()
    {
        await OnSortClick.InvokeAsync((columnName, true));
    }
}

I hope you understand what I am trying to achieve and can help me. Im a beginner in Blazor btw.

The error I get is CS1503

ChatGPT but didnt really help

1

There are 1 answers

0
RBee On BEST ANSWER

Because you're passing an anonymous tuple as the EventCallback payload.

[Parameter] public EventCallback<(string, bool)> OnSortClick { get; set; }

The LoadProjects(string column, bool asc) method cannot automatically deconstruct the tuple to your local variables. So you need to declare the parameter that the method will accept more explicitly and then you can use the column and asc variables like so.

private async Task LoadProjects((string column, bool asc) tuple)
{
    // just use it directly
    tuple.column;
    tuple.asc;
    
    // or deconstruct to local variables
    string column = tuple.column;
    bool asc = tuple.asc;
    
    // or a shorthand deconstruction
    var (column, asc) = tuple;
}

IMO it's not a good practice to pass tuples in EventCallbacks as it adds unnecessary complexity to the paramters, especially considering you already have the ColumnName as a public parameter and access to it outside of the component.

Snippet demo


In the demo i've made the following changes.

  1. I've changed your sort method clicks to call the same HandleClick method where each icon will pass a different bool parameter e.g. @onclick="(e)=>HandleClick(true)"
  2. The ColumnName property to PascalCase as is the convention when naming public parameters in Blazor.
<svg class="ml-[10px]" xmlns="http://www.w3.org/2000/svg" width="16" height="20" viewBox="0 0 16 20" fill="none">
    <path d="M8 0L14.4952 7.5H1.50481L8 0Z" fill="#C0C5CA" @onclick="(e)=>HandleClick(true)" />
    <path d="M2.59926 13L8 19.2362L13.4007 13H2.59926Z" fill="#C0C5CA" stroke="#C0C5CA" @onclick="(e)=>HandleClick(false)"/>
</svg>

@code{
    [Parameter] public string ColumnName { get; set; }
    [Parameter] public EventCallback<(string, bool)> OnSortClick { get; set; }

    private async Task HandleClick(bool isAsc)
    {
        await OnSortClick.InvokeAsync((ColumnName,isAsc));
    }
}