question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Callbacks with return value not supported on server-side Blazor

See original GitHub issue

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

  • Similar explanation to this issue in an issue comment.
  • Reworking the interop layer to be more robust and minimizing the boilerplate code required for new callbacks is the start of realizing #62, #41 and much more.

cc @mariusmuntean, @netcorefan

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:2
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

3reactions
thomasclaudiushubercommented, Mar 31, 2020

Hey @Joelius300,

it’s a great question.

I don’t have a proper solution, but I can say that you’re not alone with this problem…

In one application I did a port of Ag-Grid to Blazor, and I had exactly the same issue. Everything works good, selection, column definitions etc. But the Ag-Grid allows also custom cell renderers. And these are synchronous JavaScript functions that return a piece of HTML.

I got it working without issues in Blazor WASM with synchronous JS calls. But in Blazor Server, I was tackling exactly the same problems like you.

Cheers, Thomas

0reactions
Joelius300commented, Apr 9, 2020

From my side #70 is now complete. I’ve decided to keep the warning and document it accordingly once we’re done. It’ll be in the wiki and the readme as well. This change is part of release 2.0 where we’ll also need to invest some time into better documentation.

It’s unfortunate that this can’t be supported on server-side but as of today, there appears to be no way to make it possible.

I will remove the discussion label to this. However, it’ll stay open for any progress made in this area. I highly doubt that this is something we can support but it’s definitely something we want to support so it’ll stay. Because this will be a big question asked by many, this issue will be pinned again once the feature releases.

We’re very grateful for any insights you can share on this.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to get return value from EventCallback in blazor?
I tried using EventCallback but looks like I can't get a return value from EventCallback ? I have no idea. c# · blazor...
Read more >
ASP.NET Core Blazor event handling
Learn about Blazor's event handling features, including event argument types, event callbacks, and managing default browser events.
Read more >
How To Send Callback To Js Interop In Blazor
How to send callback method to JSInterop in Blazor ? Blazor client-side or server side can handle only CPU bound calculation. For every ......
Read more >
3 Ways to Communicate Between Components in Blazor
In this post, I show you 3 different options you can use to manage communication between components in your Blazor applications.
Read more >
Return value to client during callback
I tried using an ASPxHidden control to store the value of the variable - then retrieve it on the client side - but...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found