Javascript: Event inside a function object created with the new keyword - javascript

I have a C# COM DLL ("This.That") that has events, which I've tested using JS and they work fine. I'm now trying to wrap all my tested code inside an object. The following example works fine:
var oTest = new Test();
function Test()
{
var oDevice = new ActiveXObject("This.That");
this.CancelOperation = function()
{
try
{
oDevice.CancelOperation();
return "CancelOperation successful.";
}
catch (e)
{
return e.message;
}
};
}
But once I try to add an event to it, it doesn't work. It looks like it's probably bad syntax. I can't find any resources online that explain how this is done.
var oTest = new Test();
function Test()
{
var oDevice = new ActiveXObject("This.That");
this.CancelOperation = function()
{
try
{
oDevice.CancelOperation();
return "CancelOperation successful.";
}
catch (e)
{
return e.message;
}
};
oDevice::DeviceStatusUpdate(wasSuccess, message, data) = function()
{
document.getElementById("outBox").value += "Success: " + wasSuccess.toString() + "\nMessage: " + message + "\nData:" + data + "\n\n";
};
}

I've gotten something working but I'd still like to see other answers. This puts the event handler outside of the JS file and into the document, but the code itself is still inside the JS file. The organization of the code was my greatest concern so this is acceptable to me.
var oTest = new Test();
function Test()
{
var oDevice = new ActiveXObject("This.That");
this.CancelOperation = function()
{
try
{
oDevice.CancelOperation();
return "CancelOperation successful.";
}
catch (e)
{
return e.message;
}
};
this.WireEvents = function()
{
var script = document.createElement("script");
script.type = "text/javascript";
script.text = 'function oTest.oDevice::DeviceStatusUpdate(wasSuccess, message, data) { document.getElementById("outBox").value += "Success: " + wasSuccess.toString() + "\\nMessage: " + message + "\\nData:" + data + "\\n\\n"; }';
document.body.appendChild(script);
};
}

Related

TryCatch with Websocket on two IPs is not handled in javascript

I have a websocket listening on some interfaces so the client could call more than one ip. I don't have a dns for these IPs. This failes even in the try block
window.onload = function() {
ws = "";
try {
ws_connection = "ws://" + lblInfoIP.value + ":9080/websockets";
ws = new WebSocket(ws_connection);
}
catch(err) {
ws_connection = "ws://127.0.01:9080/websockets";
ws = new WebSocket(ws_connection);
}
ws.onmessage = function(msg) { showInfo(msg.data); };
ws.onerror = function(evt){ alert ('Websocket failed with ' + evt.data) };
}
manually using the same ip as the called url works.
How would I correctly handle that ?
Is there somesthing like ws_connection = "ws://" + called_url + "/websockets"; ?
Instead of your try/catch construct, use a simple "or" (||) operation:
window.onload = function () {
let ws = new WebSocket(`ws://${lblInfoIP.value || "127.0.01:9080"}/websockets`)
ws.onmessage = function (msg) { showInfo(msg.data); };
ws.onerror = function (evt) { alert('Websocket failed with ' + evt.data) };
}
In development, set lblInfoIP.value to null or "undefined".
Or use "document.location.host:9080"

Javascript capture errors

I'm using window.error to try to capture all client side errors.
It's working fine with Javascript errors but It doesn't capture all errors like Network Errors, or AJAX errors.
This is my code (I can't use jQuery, so is not possible to use .ajaxError):
window.onerror = function(messageOrEvent, source, lineno, colno, error) {
console.log("Captured: " + messageOrEvent)
}
This is the result:
Anyone knows a way to capture ALL errors on the client side?
Thanks
Maybe hook over the default request object:
(function(orig){
window.XMLHttpRequest=function(...args){
var instance=new orig(...args);
instance.addEventListener("readyStateChange",function(){
if(instance.status!==200){
throw new Error(instance.status+":"+instance.statusText);
}
});
return instance;
};
})(XMLHttpRequest);
I've found a way. This is my code. I think that this capture all errors.
// JavaScript Errors
window.onerror = function(messageOrEvent, source, lineno, colno, error) {
console.log("Captured: " + messageOrEvent)
}
// 404 FILES
window.addEventListener('error', function(e) {
console.log(e);
}, true);
// AJAX Errors
var open = window.XMLHttpRequest.prototype.open,
send = window.XMLHttpRequest.prototype.send;
function openReplacement(method, url, async, user, password) {
this._url = url;
return open.apply(this, arguments);
}
function sendReplacement(data) {
if(this.onreadystatechange) {
this._onreadystatechange = this.onreadystatechange;
}
this.onreadystatechange = onReadyStateChangeReplacement;
return send.apply(this, arguments);
}
function onReadyStateChangeReplacement() {
// CAPTURE HERE.
if(this.status != 200){
console.log(this.responseURL + " " + this.status + " " + this.statusText);
}
if(this._onreadystatechange) {
return this._onreadystatechange.apply(this, arguments);
}
}
window.XMLHttpRequest.prototype.open = openReplacement;
window.XMLHttpRequest.prototype.send = sendReplacement;

IndexedDB open DB request weird behavior

I have an app (questionnaire) that uses indexedDB.
We have one database and several stores in it.
Stores have data already stored in them.
At some point a dashboard html file is loaded. In this file I am calling couple of functions:
function init(){
adjustUsedScreenHeight();
db_init();
setInstitutionInstRow();
loadRecommendations();
loadResultsFromDB();
fillEvaluations();
document.addEventListener("deviceready", onDeviceReady, function(e) {console.log(e);});
}
The init() function is called on body onLoad.
setInstitutionInstRow() looks like these:
function setInstitutionInstRow(localId){
//localId = 10;
if (localId == undefined){
console.log("Localid underfined: ");
//open db, open objectstore;
var request = indexedDB.open("kcapp_db", "1.0");
request.onsuccess = function() {
var db = request.result;
var tx = db.transaction ("LOCALINSTITUTIONS", "readonly");
var store = tx.objectStore("LOCALINSTITUTIONS");
tx.oncomplete = function(){
db.close();
}
tx.onerror = function(){
console.log("Transaction error on setInstInstRow");
}
var cursor = store.openCursor();
cursor.onsuccess= function () {
var match = cursor.result;
console.log ("Retrieved item: " + match.value.instid);
// alert("Added new data");
if (match){
setInstituionInstRow(match.value.instid);
console.log("Got localid: " + math.value.instid);
}
else
console.log("localinsid: it is empty " );
};
cursor.onerror = function () {
console.log("Error: " + item.result.errorCode);
}
}
request.onerror = function () {
console.log("Error: " + request.result.errorCode );
}
request.oncomplete = function (){
console.log("The transaction is done: setInstitutionRow()");
}
request.onupgradeneeded = function (){
console.log("Upgrade needed ...");
}
request.onblocked = function(){
console.log("DB is Blocked ...");
}
} else {
instid = localId;
var now = new Date();
//console.log("["+now.getTime()+"]setInstituionInstRow - instid set to "+localId);
//open db, open objectstore;
var request = indexedDB.open("kcapp_db", "1.0");
request.onsuccess = function() {
var db = this.result;
var tx = db.transaction ("INSTITUTIONS", "readonly");
var store = tx.objectStore("INSTITUTIONS");
var item = store.get(localId);
console.log(item);
item.onsuccess= function () {
console.log ("Retrieved item: ");
if (item.length > 0)
var lInstitution = item.result.value;
kitaDisplayValue = lInstitution.krippe;
};
item.onerror = function () {
console.log("Error: " + item.result.errorCode);
}
}
request.onerror = function () {
console.log("Error: " + request.result.errorCode );
}
}
Now the problem is,
var request = indexedDB.open("kcapp_db", "1.0");
the above request is never getting into any onsuccess, oncomplete, onerror states. I debugged with Chrome tools, it never getting into any above states.
Accordingly I am not getting any data from transactions.
And there are no errors in Chrome console.
And here is the request value from Chrome dev:
From above image the readyState: done , which means it should fire an event (success, error, blocked etc). But it is not going into any of them.
I am looking into it, and still can not figure out why it is not working.
Have to mention that the other functions from init() is behaving the same way.
Looking forward to get some help.
You may be using an invalid version parameter to the open function. Try indexedDB.open('kcapp_db', 1); instead.
Like Josh said, your version parameter should be an integer, not a string.
Your request object can get 4 events in response to the open request: success, error, upgradeneeded, or blocked. Add event listeners for all of those (e.g. request.onblocked = ...) and see which one is getting fired.
I had that problem but only with the "onupgradeneeded" event. I fixed it changing the name of the "open" function. At the begining I had a very long name; I changed it for a short one and start working. I don't know if this is the real problem but it was solved at that moment.
My code:
if (this.isSupported) {
this.openRequest = indexedDB.open("OrdenesMant", 1);
/**
* Creación de la base de datos con tablas y claves primarias
*/
this.openRequest.onupgradeneeded = function(oEvent) {
...
Hope it works for you as well.

Ping with javascript and read the errors

I'm basically following the accepted answer to this question (Is it possible to ping a server from Javascript?)
Update
It seems to work as expected when the domain is 15 characters long (actually, http:// + 15, but 16 or more causes it to bomb. More details at the bottom.
The issue I'm seeing is that if you're using something that seems like a valid domain, for example http://thisisdefinitelynotarealdomainname.com, it returns an error but the code mentioned considers errors okay (because most should be). Looking at the error event, I'm not sure I see where I could get the HTTP response code (i.e., if it's a 404, consider it invalid).
Here is a jsFiddle showing the problem -- they all display "responded". If you look in the console, the invalid domain returns a 404 error, and the two valid ones (if in chrome console, not sure about the others) show that they were interpreted as an image but transferred as text/html -- is there any way to read either the 404 error, or the mime type?
var pinger = function () {
var ping = function (ip, callback) {
if (!this.inUse) {
this.status = 'unchecked';
this.inUse = true;
this.callback = callback;
this.ip = ip;
var _that = this;
this.img = new Image();
this.img.onload = function () {
_that.inUse = false;
_that.callback('responded');
};
this.img.onerror = function (e) {
if (_that.inUse) {
_that.inUse = false;
_that.callback('responded', e);
}
console.log(e);
};
this.start = new Date().getTime();
this.img.src = "http://" + ip + "/?now=" + this.start; // add the current time to work around caching
this.time = setTimeout(function () {
if (_that.inUse) {
_that.inUse = false;
_that.callback('timeout');
}
}, 1500);
}
}
return {
ping: ping
};
}();
(function () {
var output = document.getElementById('output');
var servers = [
'localhost',
'google.com',
'okthisreallydoesntmakeanysense',
'okthisreallydoe',
'thisisashortone',
'thisisabitlonger'
];
servers.forEach(function (server) {
new pinger.ping(server, function (status, e) {
output.innerHTML += server + ': ' + status + '<br />';
});
});
})();
Update
What's even more weird is that it seems to be fine up until 15 characters. I've updated the jsFiddle. See below on ones that respond how I'd expect vs ones that don't. What might cause this?
'localhost',
'google.com',
'okthisreallydoesntmakeanysense', // doesn't work
'okthisreallydoe', // works (15 characters)
'thisisashortone', // works (15 characters)
'thisisabitlonger' // doesn't work (16 characters)
This might help.
function Pinger_ping(ip, callback) {
if(!this.inUse) {
this.inUse = true;
this.callback = callback
this.ip = ip;
var _that = this;
this.img = new Image();
this.img.onload = function() {_that.good();};
this.img.onerror = function() {_that.good();};
this.start = new Date().getTime();
this.img.src = "http://" + ip;
this.timer = setTimeout(function() { _that.bad();}, 1500);
}
}
Let me know if it works

Public methods in javascript OOP

I want to make a javascript class with methods which I can call within the class as well as outside of the class. I want to make a "public" method, if you will. I want getTextAreaElement and appendTextArea to be such methods.
I've shown a snippet of best code I could come up with so far. I've also tried defining the methods as prototypes as well as within the class (this.func = ...). But that only allowed me to call the method outside (new Socket().appendTextArea("osgjr89");) but NOT within the class itself! The code snippet below shows the exact opposite implementation where I can't call the method outside of the class but can call it within.
Error:
Uncaught TypeError: Object #Socket has no method 'appendTextArea'
socket.js:
function Socket() {
var socket;
var canvas = document.getElementById('c');
var context = canvas.getContext("2d");
if (window.WebSocket) {
socket = new WebSocket("ws://localhost:9012/websocket");
socket.binaryType = 'arraybuffer';
socket.onopen = onopen;
socket.onmessage = onmessage;
socket.onerror = onerror;
socket.onclose = onclose;
} else {
alert("Your browser does not support Web Socket.");
}
function getTextAreaElement() {
return document.getElementById('responseText');
}
function appendTextArea(newData) {
var el = getTextAreaElement();
el.value = el.value + '\n' + newData + " :)";
}
function onopen(event) {
getTextAreaElement().value = "Web Socket opened!";
}
/*[...]*/
}
main.js (loads after socket.js)
$(document).ready(function() {
var s = new Socket();
s.appendTextArea("osgjr89"); // ERROR!
});
UPDATED socket.js:
function Socket() {
[...]
if (window.WebSocket) {
socket = new WebSocket("ws://localhost:9012/websocket");
socket.binaryType = 'arraybuffer';
socket.onopen = this.onopen;
socket.onmessage = this.onmessage;
socket.onerror = this.onerror;
socket.onclose = this.onclose;
} else {
alert("Your browser does not support Web Socket.");
}
this.getTextAreaElement = function() {
return document.getElementById('responseText');
}
this.appendTextArea = function(newData) {
var el = this.getTextAreaElement();
el.value = el.value + '\n' + newData + " :)";
}
this.onopen = function(event) {
this.getTextAreaElement().value = "Web Socket opened!";
}
[...]
}
All public methods must be declared as properties, not variables/functions. So, you have to change stuff like this:
function getTextAreaElement() {
return document.getElementById('responseText');
}
into
this.getTextAreaElement = function() {
return document.getElementById('responseText');
}
If you do this.func = function() {}, you can call the function inside the Constructor (Socket in your case) using this.func() as well as outside using:
var s = new Socket();
s.func();

Categories

Resources