Web Speech API: Dom Exception 11 - javascript

I'm trying to use the web speech API in Chrome 27 with the following code -
$(function(){
initRecognition();
});
function initRecognition(){
if(window.recognition !== undefined){
window.recognition.stop();
window.recognition.start();
// ^--- Exception is being thrown at this line
}else{
window.recognition = new webkitSpeechRecognition();
window.recognition.onresult = function(event) {
if (event.results.length > 0) {
command.value = event.results[0][0].transcript;
return execute();
}else{
command.value = "*&#^$&#^#?";
return execute();
}
};
window.recognition.continuous = true;
window.recognition.start();
}
}
function execute(){
// some code
initRecognition();
return false;
}
When the page loads, it asks for permission to start recognition. It recognizes one word or phrase and then stops with the following error -
Uncaught Error: InvalidStateError: DOM Exception 11
initRecognition
execute
window.recognition.onresult
There seem to be lack of resources for this. So having some trouble in troubleshooting. Any idea?

It seems if I set continuous to true, I don't have to stop() and start() every time. And calling stop() is what was causing the problem I think. So I removed those statements and it's working fine. :)
$(function(){
initRecognition();
});
function initRecognition(){
window.recognition = new webkitSpeechRecognition();
window.recognition.onresult = function(event) {
console.log(event.results);
console.log(event.results.length);
if (event.results.length > 0) {
command.value = event.results[event.results.length-1][0].transcript;
return execute();
}else{
command.value = "*&#^$&#^#?";
return execute();
}
};
window.recognition.continuous = true;
window.recognition.start();
}
function execute(){
// some code
return false;
}
Although, for some reason, event.results is acting like a stack if continuous = true . So I'm fetching the last result of the stack. But I'm sure there are other bugs waiting for me with this.

Related

WebRTC-Problem: Cannot create answer in stable (no Chrome but AJAX signalizing involved)

can somebody help me out a little? I am a little stuck.
I am trying to write a signaling process with ajax and a database involved (this is just for learning the basics of WebRTC for now).
I am receiving the SDP fine from the JSON-object as it seems, but then I always get an error "Cannot create answer in stable" when I try to create an answer in get_remote_offer() for pc_partner.
I am pretty sure it is something obvious, but I am pretty new to WebRTC and just can't see what.
I am using Firefox here and just trying to connect two instances of it (one in private mode, one in "normal" mode, but I am trying to make it work for remote users.
This is my code:
var opt;
var video_el_partner;
var video_el_local;
var pc_partner;
var pc_local;
var interval_gro;
var remote_offer_available = false;
var service_url = "https://xyz.de/webrtc";
var pwd = "xxx";
var signaling_url = "https://xyz.de/webrtc/sdp_transfer.php";
function init_stream(video_partner_id, video_local_id, allow_video, allow_audio){
if (location.protocol === 'https:') { // only possible for https!
pc_local = new RTCPeerConnection();
pc_partner = new RTCPeerConnection();
if(document.getElementById(video_partner_id) != null){
video_el_partner = document.getElementById(video_partner_id);
video_el_local = document.getElementById(video_local_id);
if(allow_video == null){
allow_video = true;
}
if(allow_audio == null){
allow_audio = true;
}
opt = { audio: allow_audio, video: allow_video };
if(typeof navigator != 'undefined' && typeof navigator.mediaDevices != 'undefined' && navigator.mediaDevices.getUserMedia != null){
navigator.mediaDevices.getUserMedia(opt).then (
function (this_stream){
// local video directly into video element:
video_el_local.srcObject = this_stream;
// remote one is more insteresting:
pc_local.addStream(this_stream);
pc_local.createOffer().then(
function (this_sdp) {
// sdp (session dependend protocol object) is now available... this would need to go to a server somehow now.
// they use socket.io for that... maybe I can use my own thing to do that?
pc_local.setLocalDescription(this_sdp);
var this_sdp_json = JSON.stringify(this_sdp)
var params_ins = "mode=insert_offer&sdp_con=" + this_sdp_json + "&pass=" + pwd + "&service_url=" + service_url;
ajax_request_simple (
signaling_url,
params_ins,
function (res_ins) {
// insert done. Lets read for another candidate.
console.log('Set Interval!');
interval_gro = window.setInterval('get_remote_offer();', 5000);
}
);
}
);
}
).catch(
function (error) {
console.log('Problem: ');
console.log(error);
}
);
} else {
console.log("navgiator or navigator.mediaDevices is not defined.");
}
}
} else {
console.log('init_stream(): We can only do anything like that on https-connections! Http is not supported by the browser!');
}
}
window.onload = function () {
document.getElementById('button_start_stream').onclick = function () {
init_stream('video_partner', 'video_local', true, false);
}
}
function is_json_str(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
function get_remote_offer() {
var params_read = "mode=get_offer&pass=" + pwd + "&service_url=" + service_url;
ajax_request_simple (
signaling_url,
params_read,
function (res_read) {
// done.
if(is_json_str(res_read)){
// seems like we get one now.
// lets use that to connect and stream the video to the remote view.
var partner_offer = res_read;
partner_offer = JSON.parse(partner_offer);
// clear interval if found.
window.clearInterval(interval_gro);
console.log('Cleared Interval. Found!');
pc_local.setRemoteDescription(
new RTCSessionDescription(partner_offer), function(){
// video_el_partner.srcObject = event.stream;
pc_local.onicecandidate = function (e) {
if ( e.candidate != null ) {
pc_partner.addIceCandidate( new RTCIceCandidate(e.candidate) );
}
};
pc_partner.onicecandidate = function (e) {
if ( e.candidate != null ) {
pc_local.addIceCandidate( new RTCIceCandidate(e.candidate) );
}
};
pc_partner.createAnswer(
function (offer) {
pc_local.setRemoteDescription(offer);
pc_partner.setLocalDescription(offer);
}
);
// pc_local.ontrack = function (evt) {
// video_el_local.srcObject = evt.stream;
// };
pc_partner.ontrack = function (evt) {
video_el_partner.srcObject = evt.stream;
};
},
function(e) {
console.log("Problem while doing client-answer: ", e);
}
);
} else {
console.log("Can not parse: ");
console.log(res_read);
}
}
);
}
Sorry for the mix of promises and callbacks... I tried a couple of things out just in case... when it is working I will rewrite the callback parts.
Thank you very much in advance for any hint you can give me :).
Best regards and thanks for reading till now ;).
Fuchur

Google Cloud SQL not updating with script

I have a long script which is designed to edit a specific row in the Cloud SQL table. The code is long so i will shorten it.
Client Side:
function build_profile(){
var cbid = sessionStorage.getItem("client_id");
var self = this;
var createSuccess = function(data){
var statuse = ["Active", "Wiating", "Discharged"];
if(data !== false){
data = data.split(",");
var dec = app.pages.Profile.descendants;
dec.fname.text = data[1];
dec.sname.text = data[3];
sessionStorage.setItem("school_id", data[9]);
app.popups.Loading.visible = false;
}
};
var init = function() {google.script.run.withSuccessHandler(createSuccess).get_user_data(cbid);};
app.popups.Loading.visible = true;
init();
}
function save_profile() {
var createSuccess = function(data){
var dec = app.pages.Profile.descendants;
console.log(data);
if(data !== -1){
var ds = app.datasources.Clients;
ds.load(function(){
ds.selectIndex(data);
console.log("editing:"+ds.item.CBID);
ds.item.fname = dec.fname_edit.value;
ds.item.sname = dec.sname_edit.value;
ds.load(function(){build_profile();});
});
}
}};
var init = function() {google.script.run.withSuccessHandler(createSuccess).update_client(sessionStorage.getItem("client_id"));};
init();
}
Server Side:
function get_user_data(cbid){
try{
var query = app.models.Clients.newQuery();
query.filters.CBID._equals = parseInt(cbid);
var results = query.run();
if(results.length > 0){
var arr = [
results[0].Id, //0
results[0].fname, //1
results[0].sname //3
];
return arr.join(",");
}else{
return false;
}
}catch(e){
console.error(e);
console.log("function get_user_data");
return false;
}
}
function update_client(cbid) {
try{
var ds = app.models.Clients;
var query = ds.newQuery();
query.filters.CBID._equals = parseInt(cbid);
var results = query.run();
if(results.length > 0){
var id = results[0]._key;
return id+1;
}else{
return -1;
}
}catch(e){
console.error(e);
return -1;
}
}
This gets the Clients table and updates the row for the selected client, then rebuilds the profile with the new information.
EDIT: I have managed to get to a point where its telling me that i cannot run the query (ds.load()) while processing its results. There does not seem to be a manual check to see if it has processed?
Note: datasource.saveChanges() does not work as it saves automatically.
You error is being produced by the client side function save_profile() and it is exactly in this block:
ds.load(function(){
ds.selectIndex(data);
console.log("editing:"+ds.item.CBID);
ds.item.fname = dec.fname_edit.value;
ds.item.sname = dec.sname_edit.value;
ds.load(function(){build_profile();});
});
So what you are doing is reloading the datasource almost immediately before it finishes loading hence you are getting that error
cannot run the query (ds.load()) while processing its results
This is just a matter of timing. A setTimeout can take of the issue. Just do the following:
ds.load(function(){
ds.selectIndex(data);
console.log("editing:"+ds.item.CBID);
ds.item.fname = dec.fname_edit.value;
ds.item.sname = dec.sname_edit.value;
setTimeout(function(){
ds.load(function(){build_profile();});
},1000);
});
I have manage to find a solution to this particular issue. It requires Manual Saving but it saves a lot of hassle as one of the inbuilt solutions can be used rather than relying on dealing with errors or timeouts.
function client_query_and_result(){
var createSuccess = function(data){ //callback function
console.log(data);
};
app.datasources.SomeTable.saveChanges(function(){//ensures all changes have been saved
app.datasources.SomeTable.load(function(){//makes sure to reload the datasource
google.script.run.withSuccessHandler(createSuccess).server_query_and_result(); //at this point All data has been saved and reloaded
});
});
}
The Server side code is the exact same methods. To enable manual saving you can select the table in App Maker -> Datasources -> check "Manual save mode".
Hope this can be useful to someone else.

Meteor publish undefined or Publish function can only return a Cursor or an array of Cursors

Having some wired issues with my Meteor publish when I have findOne it works but with find it does not and with findOne I get a cursor error.
Here is my code
Meteor.publish('organizations', function() {
var user = Meteor.users.findOne(this.userId);
if(!user) return '';
var debugTest = Organizations.findOne(user.organizationId);
console.log(debugTest._id);
//return Organizations.findOne({_id: user.organizationId});
});
For this I get undefined
If I do the following
Meteor.publish('organizations', function() {
var user = Meteor.users.findOne(this.userId);
if(!user) return '';
console.log(user.organizationId);
var debugTest = Organizations.findOne(user.organizationId);
console.log(debugTest._id);
//return Organizations.findOne({_id: user.organizationId});
});
I get back both ID's but with the return I get the following error
Teh I
NvoF9MimZ6tJ95c3m
NvoF9MimZ6tJ95c3m
The error
Exception from sub KLnQphHTXmQcjEi2D Error: Publish function can only return a Cursor or an array of Cursors
findOne does not return a Mongo cursor. It returns a Mongo document. If you want this to work, try changing to using return Organizations.find({_id: user.organizationId}); instead. That will return a single document cursor which is what the publish call expects.
For more info check out the docs.
So the issue was due to my template the pub/sub was working fine but in my template helper I had the following which was causing the issue.
hasOrganization: function() {
var user = Meteor.user();
var organizationsCount = Organizations.find({$or:[{userId: user._id},{**userId**: user.organizationId}]}).count();
console.log(organizationsCount);
if (organizationsCount >= 1) {
return true
} else {
return false
}
Here is the fixed version
hasOrganization: function() {
var organizationsCount = Organizations.find().count();
if (organizationsCount >= 1) {
return true
} else {
return false
}
}

Strophe.js register plugin not working

I have Ejabberd server hosted in remote location. And I am trying to register new accounts using Strophe.js register plugin I could not find why this is not working. Below is the code I have written
var connection = new Strophe.Connection("http://ip-address:5222/http-bind");
var callback = function (status) {
alert(Strophe.Status.REGISTER); // Returning me 10
if (status === Strophe.Status.REGISTER) {
alert("Entered");
connection.register.fields.username = "hello";
connection.register.fields.password = "hello";
connection.register.submit();
} else if (status === Strophe.Status.REGISTERED) {
alert("registered!");
connection.authenticate();
} else if (status === Strophe.Status.CONNECTED) {
alert("logged in!");
} else {
// Sometimes execution entering into this block.
document.body.innerHTML = (JSON.stringify(status));
}
};
connection.register.connect("localhost", callback);
Any extra code to be added to this or any fix I have to do make this work. Please help me on this. Strophe.js documentation is awful.
In strophe.register.js go to line no 215 and make change as per below code.
/*if (register.length === 0) {
that._changeConnectStatus(Strophe.Status.REGIFAIL, null);
return;
} else */
this.enabled = true;
Try above one.
var connection = new Strophe.Connection("http://ip-address:5222/http-bind/");
Trailing Slash is needed at the end.

Understanding try..catch in Javascript

I have this try and catch problem. I am trying to redirect to a different page. But sometimes it does and some times it doesnt. I think the problem is in try and catch . can someone help me understand this. Thanks
var pg = new Object();
var da = document.all;
var wo = window.opener;
pg.changeHideReasonID = function(){
if(pg.hideReasonID.value == 0 && pg.hideReasonID.selectedIndex > 0){
pg.otherReason.style.backgroundColor = "ffffff";
pg.otherReason.disabled = 0;
pg.otherReason.focus();
} else {
pg.otherReason.style.backgroundColor = "f5f5f5";
pg.otherReason.disabled = 1;
}
}
pg.exit = function(pid){
try {
if(window.opener.hideRecordReload){
window.opener.hideRecordReload(pg.recordID, pg.recordTypeID);
} else {
window.opener.pg.hideRecord(pg.recordID, pg.recordTypeID);
}
} catch(e) {}
try {
window.opener.pg.hideEncounter(pg.recordID);
} catch(e) {}
try {
window.opener.pg.hideRecordResponse(pg.hideReasonID.value == 0 ? pg.otherReason.value : pg.hideReasonID.options[pg.hideReasonID.selectedIndex].text);
} catch(e) {}
try {
window.opener.pg.hideRecord_Response(pg.recordID, pg.recordTypeID);
} catch(e) {}
try {
window.opener.pg.hideRecord_Response(pg.recordID, pg.recordTypeID);
} catch(e) {}
try {
window.opener.window.parent.frames[1].pg.loadQualityMeasureRequest();
} catch(e) {}
try {
window.opener.pg.closeWindow();
} catch(e) {}
parent.loadCenter2({reportName:'redirectedpage',patientID:pid});
parent.$.fancybox.close();
}
pg.hideRecord = function(){
var pid = this.pid;
pg.otherReason.value = pg.otherReason.value.trim();
if(pg.hideReasonID.selectedIndex == 0){
alert("You have not indicated your reason for hiding this record.");
pg.hideReasonID.focus();
} else if(pg.hideReasonID.value == 0 && pg.hideReasonID.selectedIndex > 0 && pg.otherReason.value.length < 2){
alert("You have indicated that you wish to enter a reason\nnot on the list, but you have not entered a reason.");
pg.otherReason.focus();
} else {
pg.workin(1);
var n = new Object();
n.noheaders = 1;
n.recordID = pg.recordID;
n.recordType = pg.recordType;
n.recordTypeID = pg.recordTypeID;
n.encounterID = request.encounterID;
n.hideReasonID = pg.hideReasonID.value;
n.hideReason = pg.hideReasonID.value == 0 ? pg.otherReason.value : pg.hideReasonID.options[pg.hideReasonID.selectedIndex].text;
Connect.Ajax.Post("/emr/hideRecord/act_hideRecord.php", n, pg.exit(pid));
}
}
pg.init = function(){
pg.blocker = da.blocker;
pg.hourglass = da.hourglass;
pg.content = da.pageContent;
pg.recordType = da.recordType.value;
pg.recordID = parseInt(da.recordID.value);
pg.recordTypeID = parseInt(da.recordTypeID.value);
pg.information = da.information;
pg.hideReasonID = da.hideReasonID;
pg.hideReasonID.onchange = pg.changeHideReasonID;
pg.hideReasonID.tabIndex = 1;
pg.otherReason = da.otherReason;
pg.otherReason.tabIndex = 2;
pg.otherReason.onblur = function(){
this.value = this.value.trim();
}
pg.otherReason.onfocus = function(){
this.select();
}
pg.btnCancel = da.btnCancel;
pg.btnCancel.tabIndex = 4;
pg.btnCancel.title = "Close this window";
pg.btnCancel.onclick = function(){
//window.close();
parent.$.fancybox.close();
}
pg.btnHide = da.btnHide;
pg.btnHide.tabIndex = 3;
pg.btnHide.onclick = pg.hideRecord;
pg.btnHide.title = "Hide " + pg.recordType.toLowerCase() + " record";
document.body.onselectstart = function(){
if(event.srcElement.tagName.search(/INPUT|TEXT/i)){
return false;
}
}
pg.workin(0);
}
pg.workin = function(){
var n = arguments.length ? arguments[0] : 1;
pg.content.disabled = pg.hideReasonID.disabled = n;
pg.blocker.style.display = pg.hourglass.style.display = n ? "block" : "none";
if(n){
pg.otherReason.disabled = 1;
pg.otherReason.style.backgroundColor = "f5f5f5";
} else {
pg.otherReason.disabled = !(pg.hideReasonID.value == 0 && pg.hideReasonID.selectedIndex > 0);
pg.otherReason.style.backgroundColor = pg.otherReason.disabled ? "f5f5f5" : "ffffff";
pg.hideReasonID.focus();
}
}
I think your main problem is that you're swallowing exceptions, which is very bad. This is why "it works sometimes". Something is throwing an exception, and you're catching it, but then you're not doing anything else after that. At the very least I would display some sort of error message in your catch block.
A few other problems:
Are you sure you need those multiple try..catch blocks? The current assumption in your code is that each line that is wrapped in a try..catch is independent of the others, and execution can still proceed if something goes wrong in any one (or more) of those statements. Are you sure this is what you want? If so, there is definitely a better way of handling this.
If the statements are not independent of each other, and if a failure at any point means that execution cannot proceed, then you can wrap all of those statements in a single try..catch block and display an error message in the catch
Like I said before, swallowing exceptions is very bad! You're hiding the problem and not achieving anything. It also makes debugging extremely hard, because things will stop working and you will have no idea why (no exception, no logging, no error messages). Exceptions are used when something unexpected happens that interrupts normal program flow. It is something you definitely want to handle.
I think what you want can be done this way:
try {
if(window.opener.hideRecordReload){
window.opener.hideRecordReload(pg.recordID, pg.recordTypeID);
} else {
window.opener.pg.hideRecord(pg.recordID, pg.recordTypeID);
}
window.opener.pg.hideEncounter(pg.recordID);
window.opener.pg.hideRecordResponse(pg.hideReasonID.value == 0 ? pg.otherReason.value : pg.hideReasonID.options[pg.hideReasonID.selectedIndex].text);
window.opener.pg.hideRecord_Response(pg.recordID, pg.recordTypeID);
window.opener.pg.hideRecord_Response(pg.recordID, pg.recordTypeID);
window.opener.window.parent.frames[1].pg.loadQualityMeasureRequest();
window.opener.pg.closeWindow();
}
catch(e) {
console.log(e);
}
This way, if an exception occurs anywhere along those series of statements, the catch block will handle it.
Javascript also doesn't have true checked-exceptions. You can get around it by having a single try block, and inspecting the exception object that you receive*.
Expanding on what I talked about earlier, there are two ways of handling exceptions. The first way, like I showed earlier, assumes that when an exception happens, the code is in an invalid/undefined state and this therefore means that the code encountered an unrecoverable error. Another way of handling exceptions is if you know it is something you can recover from. You can do this with a flag. So:
try {
doSomething();
}
catch(e) {
error = true;
}
if(error) {
doStuffToRecoverFromError();
}
else {
doOtherStuff();
}
In this case the flow of your logic depends on an exception being thrown. The important thing is that the exception is recoverable, and depending on whether it was thrown or not, you do different things.
*Here is a somewhat contrived example that demonstrates checked-exceptions. I have two exceptions called VeryBadException and ReallyBadException that can be thrown (randomly) from two functions. The catch block handles the exception and figures out what type of exception it is by using the instanceof operator):
function VeryBadException(message) {
this.message = message;
}
function ReallyBadException(message) {
this.message = message;
}
function foo() {
var r = Math.floor(Math.random() * 4);
if(r == 2) {
throw new VeryBadException("Something very bad happened!");
}
}
function bar() {
var r = Math.floor(Math.random() * 4);
if(r == 1) {
throw new ReallyBadException("Something REALLY bad happened!");
}
}
try {
foo();
bar();
}
catch(e) {
if(e instanceof VeryBadException) {
console.log(e.message);
}
else if(e instanceof ReallyBadException) {
console.log(e.message);
}
}
It's good practice do something with the caught exceptions.
What's happening here is that if there's an error (say loading a page fails) an exception is thrown inside one of your try blocks. The corresponding catch block grabs it and says "that exception has been dealt with" but in actuality you've not done anything with it.
Try putting a print(e.Message); inside your catch blocks to find out exactly what error is causing the page not to load and then add code to your catch block to deal with this error.

Categories

Resources