Skip to content

Callbacks with return value not supported on server-side Blazor #90

@Joelius300

Description

@Joelius300

With #70 I have reworked the interop-layer once more to provide a type-safe way of invoking any delegate from JavaScript without writing much new code on either side for different callbacks. Apart from that I also implemented the first case of callbacks that return a value (namely Custom Ticks Format callback). The procedure of such a callback is as follows:
Chart.js will first call from JavaScript into C# with some arguments which will be deserialized (that's why we need #84 and more). Then on the C# side, we can handle these arguments and produce a response that will be serialized again and returned to the JavaScript caller.

The chart.js callbacks are synchronous, not async (at least I haven't seen any). That means they expect the actual value to be returned, not a promise (or generator). This obviously means that the value has to be returned to the chart.js handler synchronously. On client-side this is quite easy because the JavaScript dispatcher from wasm blazor has the ability to invoke C# from JavaScript synchronously. But now lets talk about server-side. Server-side blazor is built on SignalR which is built on websockets. JavaScript websockets and SignalR are async (I don't know either very well but afaik they only work async). That means there is just no way to do synchronous JavaScript-C# interop.

What have I tried/considered without success:

  • Flattening the Promise object of an async JavaScript function by synchronously waiting for it. This would be the equivalent of the C# Task.Wait(). However, by the nature of JavaScript this just doesn't seem to be possible. I have asked a StackOverflow question about this and it pretty much confirmed just that it's not possible.
  • When searching for how to work with promises in a synchronous manner, I found out about an approach using generators. I have played around with it but this just shifts the issue from Promise objects to Generator objects which doesn't help us. I wrote about that approach in this issue comment.
  • Rewriting chart.js; of course not feasible.

Now the question is what to do. In the current (#70) implementation of the interop layer, it just writes a warning in the browser with console.warn() and falls back to the default handler if you supply a C# handler to a callback that expects a return value. JavaScript handlers are still fully supported and work perfectly fine even with return values.
Now I would like to know some opinions on this. What should happen when it's not supported? Is there still hope to make this work? Because I genuinely don't see any way to make this work for server-side. Is this warning enough? Where do we document this that it's discoverable and no one wastes time trying to get it to work?

What do you think?

Additional stuff

cc @mariusmuntean, @netcorefan

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions