Blazor WebbAssembly exception when calling javascript function? - javascript

I have a C# function that is invoking a Javascript function, this is the C# function:
await _jsRuntime.InvokeVoidAsync("setMediaUsingStreaming", type, dotnetImageStream);
And this is the Javascript function:
async function setMediaUsingStreaming(fileType, fileStream) {
try {
const arrayBuffer = await fileStream.arrayBuffer();
const blob = new Blob([arrayBuffer]);
const url = URL.createObjectURL(blob);
var newHTMLElement;
var fileHTMLElement = document.getElementById('fileDisplay');
if (fileType == "image") {
newHTMLElement = document.createElement('img');
}
else {
newHTMLElement = document.createElement('video');
var attribute = document.createAttribute('controls');
newHTMLElement.setAttributeNode(attribute);
}
fileHTMLElement.appendChild(newHTMLElement);
newHTMLElement.src = url;
} catch (Exception)
{
console.log(Exception)
}
}
When the C# function is invoking the Javascript function I receive this error :
blazor.webassembly.js:1 Uncaught (in promise) Error:
Microsoft.JSInterop.JSException: Cannot set properties of null
(setting 'src') TypeError: Cannot set properties of null (setting
'src')
The weird thing is that I receive this error when I run the app in publish mode (withouth a debugger) but it works perfectly in debug mode. The catch from the javascript function is not hit when I receive this error, it seems that is the C# method that is throwing it.
I know what the error is saying, that the url variable is null, but I don't understand why is null, and why it works on debug mode.
Do you have any ideas ?

Related

Parsing error in a FileReader onload function

For some reason I am getting an error with my FileReader unload function. The error is Parsing error: Invalid left-hand side in assignment expression I looked in to what that means to according to MDN web docs: "invalid assignment left-hand side" occurs when there was an unexpected assignment somewhere. For example, a single "=" sign was used instead of "==" or "===". I don't see how this would be a error.
var fileInput = files[0];
var audioCtx = new AudioContext(files[0]);
var reader1 = new FileReader();
reader1.onload() = function (ev) { //error here
//decode audio
audioCtx.decodeAudioData(ev.target.result).then(function(buffer) {
reader1.readAsArrayBuffer(fileInput.files[0]);
})
}
onload is a property, not a method.
reader1.onload = function (ev) {
...
}

Issue Parsing JSON Response

I'm using AJAX/JQuery to call a WCF service. I have some .NET try/catch error-handling on the service-side that checks to see if the user has timed out, and if they have then I pass back a JSON-converted message which I then parse out on the client-end using parseJSON and use it to re-direct the user back a login page.
This is all working great, but I just got a different type of error returned from the service that WASN'T in JSON format (it was XML) so the error-handling function got a javascript error on the client side when it tried to parse the reply. The error was in the jquery.min.js file, and was an 'Invalid character' error.
My question (finally), is there a better way to handle that reply if I can't always rely on it being JSON? In .NET we have a tryParse method available that would work great here, but as far as I know JQuery/Javascript has no such feature. If it can't parse the reply, it throws a JS error.
Here is where the custom JSON exception is thrown:
private HttpSessionState GetUserSession()
{
HttpSessionState session = HttpContext.Current.Session;
try
{
// This is a method we created that checks if user has timed out and throws the exception if so.
SessionBuilder.Create(session, HttpContext.Current.Request, HttpContext.Current.Response);
}
catch (SessionTimeOutException e)
{
throw new WebFaultException<SessionTimeOutException>(new SessionTimeOutException(e.Message), System.Net.HttpStatusCode.BadRequest);
}
return session;
}
And here is the client-side code that handles errors in my AJAX request:
error: function (HttpRequest)
{
// This is the line that gets the exception because the responseText is a standard .NET XML error, not my custom JSON error.
var parsedReply = $.parseJSON(HttpRequest.responseText);
if (parsedReply.ClassName === "SessionTimeOutException")
{
var url = "../timeout.asp?" + parsedReply.Message;
window.location.href = url;
}
}
JavaScript has try { ... } catch(ex) { ... } also.
error: function (HttpRequest)
{
var parsedReply;
try {
parseReply = $.parseJSON(HttpRequest.responseText);
if (parsedReply.ClassName === "SessionTimeOutException")
{
var url = "../timeout.asp?" + parsedReply.Message;
window.location.href = url;
}
} catch(ex) {
parsedReply = HttpRequest.responseText;
//Do something else
}
}

Using Javascript to store Data

I've seen posts on how to add Javascript dynamically, and posts on ways to store data with Javascript, and I thought of a way to store data.
I'm trying to add a Javascript file (which contains variables/data) dynamically to a page to get Level data?
EDIT: I've done more testing, I now have an onload check, but the try{ initializeLevel } is still returning an error:
ReferenceError {stack: (...), message: "initializeLevel is not defined"}
message: "initializeLevel is not defined"
stack: (...)
get stack: function () { [native code] }
set stack: function () { [native code] }
__proto__: Error
New Level.js
Level_State = new Object();
Level_State.LOADED = 1921;
Level_State.UNLOADED = 183;
Level_State.CURRENT = '';
function openLevel(src){
var element = document.getElementById('levelDat');
try{src.toString();}catch(e){}
src = 'Level/'+src+'.js';
element.src = src;
element.onload = parseLevel();
}
function parseLevel(){
alert('Parsing JS');
try{
initializeLevel();
generateLevel();
}catch(e){
closeLevel();
}
}
function closeLevel(){
alert('Error Loading JS FILE');
var element = document.getElementById('levelDat');
element.src = '';
}
function generateLevel(){
alert('Generating JS');
}
and Test.js contains
function initializeLevel(){
testMap = new MapDat('testMapTheSecond');
LevelData = new LevelDat('testLevel#2',testMap);
}

Jsdom throwing error for some URLs

I am new to nodejs, what I'm trying to do is to scan all the url of my site (with javascript and jquery enabled) and check that the url contains a given string.
To do this I'm using jsdom, but when I launch the script extracts only some url and then crashes giving this error:
timers.js:110
first._onTimeout();
^
TypeError: Property '_onTimeout' of object [object Object] is not a function
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
Surely there is something wrong but I don't understand where..
This is my script:
var request = require('request');
var jsdom = require('jsdom');
request({ uri: 'http://www.example.com' }, function (error, response, html) {
if (!error && response.statusCode == 200) {
var doc = jsdom.jsdom(html, null, {
features: {
FetchExternalResources : ['script'],
ProcessExternalResources : ['script'],
MutationEvents : '2.0',
}
});
var window = doc.createWindow();
jsdom.jQueryify(window, "http://code.jquery.com/jquery-1.5.min.js", function() {
var $ = window.jQuery;
$('a').each(function(i, element){
var a = $(this).attr('href');
console.log(a);
if (a.indexOf('string') != -1) {
console.log('The winner: '+a);
//return a;
}
});
window.close();
});
}
});
This is because of somewhere in your page they are calling setTimeout/setInterval with a string that is not supported in node and it results in that error.
To find out where is it coming from, I suggest just require longjohn module(require('longjohn')) and you get long stack traces, which they will help you to find the error. For example I got something like this from doing this in the repl:
at listOnTimeout (timers.js:110:15)
---------------------------------------------
at startTimer (/home/alfred/repos/node_modules/jsdom/lib/jsdom/browser/index.js:75:15)
at DOMWindow.setTimeout (/home/alfred/repos/node_modules/jsdom/lib/jsdom/browser/index.js:124:50)
at file:///home/alfred/repos/repl:undefined:undefined<script>:1:1
at Contextify.sandbox.run (/home/alfred/repos/node_modules/jsdom/node_modules/contextify/lib/contextify.js:12:24)
at exports.javascript (/home/alfred/repos/node_modules/jsdom/lib/jsdom/level2/languages/javascript.js:5:14)
at define.proto._eval (/home/alfred/repos/node_modules/jsdom/lib/jsdom/level2/html.js:1523:47)
at /home/alfred/repos/node_modules/jsdom/lib/jsdom/level2/html.js:76:20
at item.check (/home/alfred/repos/node_modules/jsdom/lib/jsdom/level2/html.js:345:11)
If by any chance that didn't work for you or you didn't like it, then I suggest you to modify this jsdom file: node_modules/jsdom/lib/jsdom/browser/index.js, function startTimer. Throw an error there if the callback wasn't a function. This will throw whenever offending code was run.
In case if you are running code that you can't change(like from websites you don't own, which I don't suggest it because foreign javascript like that could be used to attack your app), you could override DOMWindow.setTimeout/.setInterval to support string arguments. You could also make open an issue for jsdom to have this opt-in.

File API writing file doesn't work Samsung smart tv SDK

I have this javascript code which makes possible writing in a file
{
var fileSystemObj = new FileSystem();
var fileObj = fileSystemObj.openCommonFile(curWidget.id +
‘/testFile.data’, ‘w’);
fileObj.writeLine(‘something to write.’);
fileSystemObj.closeCommonFile(fileObj);
}
but it doesn't work. Doesn't even display any error!
samsung developer forum (you may not see unless you sign in... )
I am quoting it.
case tvKey.KEY_RED:
alert('RED BUTTON!');
alert('CWID: '+curWidget.id);
try {
var fileSystemObj = new FileSystem();
var fileObj = fileSystemObj.openCommonFile(curWidget.id+'/testFile.data','w');
fileObj.writeLine('something to write.');
fileSystemObj.closeCommonFile(fileObj);
} catch (e) {
alert('Error: file handling: '+e);
}
break;
lead to error:
alert() : Error: file handling: TypeError: 'null' is not an object
(evaluating 'fileObj.writeLine')
Reading cause same problem.
and solution accepted in that link is:
I suppose that problem is that you have to create common dir (if does not exist ) at first :
var fileObj = fileSystemObj.openCommonFile(filePath, 'w');
if(!fileObj){
var bValid = fileSystemObj.isValidCommonPath(curWidget.id);
if (!bValid) {
fileSystemObj.createCommonDir(curWidget.id);
}
}
fileObj = fileSystemObj.openCommonFile(filePath, 'w');
fileObj.writeLine('something to write.');
fileSystemObj.closeCommonFile(fileObj);

Categories

Resources