Skip to content

Blazor client onclick function with parameter #10138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ziodex opened this issue May 10, 2019 · 8 comments
Closed

Blazor client onclick function with parameter #10138

ziodex opened this issue May 10, 2019 · 8 comments
Labels
area-blazor Includes: Blazor, Razor Components

Comments

@ziodex
Copy link

ziodex commented May 10, 2019

Adding parameter to a function in Blazor client throws compiler error: Cannot convert from void to string, example:

<a onclick="@MyFunction">My function</a>

void MyFunction() {
    Console.WriteLine("Works");
}


<a onclick="@MyFunction(1)">My function</a>

void MyFunction(int number) {
    Console.WriteLine("Throws error");
}
@julienGrd
Copy link

julienGrd commented May 10, 2019

Hello, you can do this with something like that

<a onclick="@(() => MyFunction(1))">My function</a>

if you want pass args (UIEventArgs)
<a onclick="@((args) => MyFunction(args, 1))">My function</a>

good luck

@ziodex
Copy link
Author

ziodex commented May 10, 2019

Not quite.. All of these will return the last number (5)

@for(int i  = 0; i < 5; i++)
{
	<a onclick="@(() => MyFunction(i))">My function i</a><br />
}
void MyFunction(int number)
{
	Console.WriteLine(number);
}

@julienGrd
Copy link

wow you are right it's really bad !

I have a workaround which works

@{ 
    var list = new int[]{ 0, 1, 2, 3, 4 };
}

@foreach(var l in list)
{
    <a onclick="@((args) => MyFunction(args, l))">My function @l</a><br />
}

but the team have to solve it, it can't stay like that

@pranavkm pranavkm added the area-blazor Includes: Blazor, Razor Components label May 10, 2019
@KieranDevvs
Copy link

KieranDevvs commented May 10, 2019

Ok so it took me a few minutes to figure it out but here's what I believe is going on. Because you're using a lambda function to define the event, its taking i as a reference (because its a simple type) and then when the loop finishes, i is left at 5 and when the function is called, all functions just use i (5). You can confirm this by adding a copy variable in the loop to copy the var by value into the local scope of the loop.

@for(int i = 0; i < 5; i++)
{
    var a = i;
    <a href="#" onclick="@(() => test(a))">My function @a</a><br />
}

@functions {
    void test(int i)
    {
        Console.WriteLine(i);
    }
} 

I think its actually working as intended but its not obvious.
https://blogs.msdn.microsoft.com/matt/2008/03/01/understanding-variable-capturing-in-c/

@mkArtakMSFT
Copy link
Contributor

Thanks for contacting us. We believe that the question you've raised have been answered. If you still feel a need to continue the discussion, feel free to reopen it and add your comments.

@Madunet
Copy link

Madunet commented Jun 20, 2019

I have altered the counter page to demonstrate. The UI is not refreshed when you hit one of the "Set counter to" buttons.
Sample: Click "Set counter to 3" nothing happens. When you click on "Click me" the counter is set to 4.
Is this a bug in Blazor? Or is there a fix/ work around?

I am using Blazor Server Side Preview 6..

`@page "/counter"

Counter

Current count: @currentCount


Click me

@for (int i = 0; i < 5; i++)
{
    var a = i;
    <p><button class="btn btn-primary" onclick="@(() => test(a))">Set counter to @a</button></p>
}


@functions {
    int currentCount = 0;

    protected void IncrementCount()
    {
        currentCount++;

    }

    void test(int i)
    {
        currentCount = i;
    }
}

`

@Andrzej-W
Copy link

@Madunet add @ before onclick

<button class="btn btn-primary" @onclick="@(() => test(a))">Set counter to @a</button>

@Paul-Schroeder
Copy link

I needed similar syntax for invoking a method with a parameter and here is what worked for me:

Razor:
<button class="btn btn-primary" onclick="@((Action<EventArgs>) (args => RegisterClicked(args, ConferenceEvent.ConferenceEventId)))">Register</button>

Code:
private void RegisterClicked(EventArgs args, Guid conferenceEventId) { System.Diagnostics.Debug.WriteLine($"Register for {conferenceEventId}"); }

Note: I'm using RC1, which includes some changes necessary as of Preview 9:

"Replace Microsoft.AspNetCore.Components.UIEventArgs with System.EventArgs and remove the “UI” prefix from all EventArgs derived"

See: https://devblogs.microsoft.com/aspnet/asp-net-core-and-blazor-updates-in-net-core-3-0-preview-9/

@ghost ghost locked as resolved and limited conversation to collaborators Dec 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components
Projects
None yet
Development

No branches or pull requests

8 participants