0

Placed here for the sake of it, originally I wrote this question on Blazors subreddit as it was an odd question.

Problem:

I need to call StateHasChanged to let Blazor know I've changed the input fields with JS (A library I have to implement, I'm stuck with this regardless so I need to find this solution.)

Description and solutions I've tried:

I've checked an issue created 2 years back, but it does not solve my issue as each time I follow their advice of dispatching the 'change' event, nothing happens. Although, that was tested by dispatching the event on the body element since it's difficult to pin point the exact element that needs to be updated. So my current solution is trying to call StateHasChanged in hopes I can get Blazor to see the changes to the field inputs.

Other info I found:

Checked here, but they don't show calling an instanced method, they just mention it's possible but not how.

Second, I checked here, but I'd prefer not to pass around an instance of a component, just to call StateHasChanged.

Maybe I don't absolutely need to call StateHasChanged and I'm just dispatching the 'change' event improperly but there's no good examples of dispatching that event to Blazor anyway so maybe that's an even better solution.

Additional solution I've tried.

Edit 1:

I have now managed to call StateHasChanged, mind you not the way I would like it to be called but I called it, and it made no difference, Blazor still doesn't recognize the changed inputs. Guess I'll be trying the 'change' event stuff.

code:

//button in Blazor component:
<button type="button" u/onclick='async (e) => await jsRuntime.InvokeAsync<Task>("ChangeValueFromJs", DotNetObjectReference.Create(this))'>Test</button>

//code in component:
[JSInvokable("invokeFromJS")]
public Task ChangeValue()
{
    StateHasChanged(); 
    return Task.CompletedTask;
}

//Javascript on client side page:
function ChangeValueFromJs(wrapper) {
    return wrapper.invokeMethodAsync("invokeFromJS")
        .then(_ => {
            console.log('state has changed');
        });
}

1 Answer 1

0

Edit 2 (Solution):

So I ended up going the JS route dispatching the 'change' event as a solution from SteveSandersonMS on an issue someone made on the Blazor repo very similar to mine. I did however learn two things that are very important for using this solution.

  1. The event target for this dispatchEvent (element.dispatchEvent('change', { 'bubbles' : true })), element in this case, must be the input field, received from a querySelector (let element = document.querySelector("#input-field-username"))

  2. Bubbling should be true, although I haven't tested this, I think someone mentioned it in one of my referenced pages that it is important.

// Not the greatest but - submits an update for *all* input fields, not only the changed ones, maybe improve this later.
let elements = document.querySelectorAll(".address-form-input");
if (elements) 
    elements.forEach(p => p.dispatchEvent(new Event('change', { 'bubbles': true })))

Hopefully this helps anyone out there, cheers.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.