Search code examples
asynchronousasync-awaitblazorblazor-client-side

How to use a string result of an asynchronous task in a blazor component?


I have something like this in mij Index.razor file:

<div class="trials">
    @DoSomething("First try")
    @(async () => await DoSomething("Second try"))
    @DoSomething("Third try").Result
</div>

<div class="purpose">
    <h4>@DoSomething("Use the result like a title")</h4>
    <textarea placeholder="@DoSomething("Use the result like a placeholder")" />
    <button type="button" class="btn">@DoSomething("Show the result on a button")</button>
</div>


@code {
    private async Task<string> DoSomething(string text)
    {
        return await client.DoSomething(text);
    }
}

I want to show the string result of the DoSomething() on headers, buttons, placeholders etc. But I cannot get it to work. I have tried different solutions.

First try:

@DoSomething("First try")

Returns System.Threading.Tasks.Task`1[System.String] instead of the result I expect.

Second try:

@(async () => await DoSomething("Second try"))

It says this is not valid because: Cannot convert lambda expression to type 'object' because it is not a delegate type

Third try:

@DoSomething("Third try").Result

Does not come back, the application will freeze.

It is possible to store the result in a variable or property, but this is not a solution for me because I will use it like everywhere, on buttons, placeholders and stuff.

How do I show the result of DoSomething() on a header/button/placeholder/etc?


Solution

  • The 'cleanest' I can think of is a Component for the job:

    // AsyncHelper.razor    
    @result
    @code {
        [Parameter]
        public Func<string, Task<string>> Formatter { get; set; }
    
        [Parameter]
        public string Text { get; set; }
    
        private string result;
    
        protected override async Task OnParametersSetAsync()
        {
            result = await Source(Text);
        }    
    }
    

    and then use it like

    <h4><AsyncHelper Formatter="DoSomething" Text ="Use the result like a title" /></h4>