A JavaScript error appears in the browser console
blazor.server.js:1 [2019-10-29T12:25:00.705Z] Information: Normalizing '_blazor' to 'https://localhost:44387/_blazor'.
blazor.server.js:1 [2019-10-29T12:25:01.018Z] Information: WebSocket connected to wss://localhost:44387/_blazor?id=FFEeuHNqrQLnX70peuLyLg.
blazor.server.js:8 Uncaught (in promise) TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Window'
--- property 'parent' closes the circle
at JSON.stringify ()
at blazor.server.js:8
(anonymous) @ blazor.server.js:8
Promise.then (async)
beginInvokeJSFromDotNet @ blazor.server.js:8
(anonymous) @ blazor.server.js:1
e.invokeClientMethod @ blazor.server.js:1
e.processIncomingData @ blazor.server.js:1
connection.onreceive @ blazor.server.js:1
i.onmessage @ blazor.server.js:1
when opening a new tab using
JsRuntime.InvokeAsync<bool>("open", video.Link, "_blank");
This is because window.open returns a WindowProxy object (see https://developer.mozilla.org/en-US/docs/Web/API/Window/open). WindowProxy is not JSON-serializable, so can't be used as a return value to .NET code.
To fix this, don't call window.open directly, but instead call a JS function of your own that either returns nothing or returns something that is JSON-serializable.
I realized the InvokeAsync<bool> was not necessary anymore. Now there is the InvokeVoidAsync.
JsRuntime.InvokeVoidAsync("open", video.Link, "_blank");
But this is still throwing the error. In this case it shouldn't serialize anything because the code is expecting void.
IMO this should be handled by Blazor. creating Javascript to do this shouldn't be necessary.
Thanks @arivoir, that's a really good point. It's not useful for InvokeVoidAsync to serialize its return value at all, since the .NET side is going to ignore it anyway. I'm reopening this and putting it on the backlog.
You can use location.replace instead of open
Here's another repro-case (in Blazor server side, .NET5 RC2).
string s = "$('#my-button').attr('data-content', 'Hello!').popover('show')";
await JsRuntime.InvokeVoidAsync("eval", s);
This works (BTW: I know it may be bad practise to use eval and I have another solution already). But in the browser console I see this error:
blazor.server.js:1 Uncaught (in promise) TypeError: Converting circular structure to JSON
--> starting at object with constructor 'HTMLButtonElement'
| property '_blazorEvents_1' -> object with constructor 'e'
| property 'handlers' -> object with constructor 'Object'
| property 'click' -> object with constructor 'Object'
--- property 'element' closes the circle
at JSON.stringify (<anonymous>)
at blazor.server.js:1