Start object from setInterval? - javascript

I have the following reconnect method for Sockjs which almost is fully working:
(function() {
// Initialize the socket & handlers
var connectToServer = function() {
var warbleSocket = new SockJS('http://url.com:5555/warble');
warbleSocket.onopen = function() {
clearInterval(connectRetry);
$('.connect-status')
.removeClass('disconnected')
.addClass('connected')
.text('Connected');
};
warbleSocket.onmessage = function(e) {
$('#warble-msg').text(e.data);
};
warbleSocket.onclose = function() {
clearInterval(connectRetry);
connectRetry = setInterval(connectToServer, 1000);
$('.connect-status')
.removeClass('connected')
.addClass('disconnected')
.text('Disconnected');
};
// Connect the text field to the socket
$('.msg-sender').off('input').on('input', function() {
warbleSocket.send($('.msg-sender input').val());
});
function send(a) {
warbleSocket.send(a);
}
return {
send: send
};
}();
var connectRetry = setInterval(connectToServer, 1000);
})();
The error i am getting is when its trying to reconnect.
Error is:
SyntaxError: missing ] after element list
at this line:
connectRetry = setInterval(connectToServer, 1000);
Any ideas what im doing wrong here?

Your connectToServer variable is not a function, it's an object with a property send that is a function, so it doesn't make sense to say setInterval(connectToServer, 1000). Try this instead:
setInterval(connectToServer.send, 1000);

Why don't you simplify things a bit?
I would put connection stuff inside a specific function and call it from setInterval().
Something like this (use with care since I'm not testing this code, ok?):
(function() {
// Initialize the socket & handlers
var connectToServer = function() {
var warbleSocket;
function connect() {
warbleSocket = new SockJS('http://url.com:5555/warble');
warbleSocket.onopen = function() {
// ...
};
warbleSocket.onmessage = function(e) {
// ...
};
warbleSocket.onclose = function() {
// ...
}
// Connect the text field to the socket
$('.msg-sender').off('input').on('input', function() {
warbleSocket.send($('.msg-sender input').val());
});
function send(a) {
warbleSocket.send(a);
}
return {
send: send
};
}();
// you probably will need to call the first connection
connectToServer();
// and than set connection retry
var connectRetry = setInterval(connectToServer.connect, 1000);
})();
I hope it helps you.
Regards,
Heleno

Related

node js self this call method

I'm working on NodeJS and I have this module:
Manager.js
with this code (this is not all the code...):
//
// Object Manager
function Manager(params) {
client = new ModbusRTU();
}
//connessione alla seriale per lettura modbus
Manager.prototype.connectClient = function(){
// try to connect
client.connectRTUBuffered ("/dev/ttyS3", { baudRate: 19200 })
.then(function()
{
mbsState = MBS_STATE_GOOD_CONNECT;
mbsStatus = "Connected, wait for reading...";
console.log(mbsStatus);
})
.catch(function(e)
{
mbsState = MBS_STATE_FAIL_CONNECT;
mbsStatus = e.message;
console.log("Error:"+e);
});
client.setTimeout (20);
}
//read data
Manager.prototype.readData = function(){
var self = this;
client.setID(2);
// try to read data
client.readCoils (0, 7, function(error,data){
if(!error){
self.checkEmergency();
}
});
}
//emergency
Manager.prototype.checkEmergency= function(){
}
exports.Manager=Manager;
client part of code is about a modbus application.
When I try to call "self.checkEmergency()" from readData, I have this error:
"self.checkEmergency() is not a function"
Why?
The method readData is called inside a method like this:
Manager.prototype.caller= function(){
var self = this;
self.readData();
}
I also have used self to pass the object to the callback...
Any idea?

node.js modules - EventEmitter

I'm trying to create my own module for the GPIO-Pins of a Raspberry Pi but I want to receive .on('something', function() { }) events, if something changed (like a button is pressed/released).
The python script sends every 0.01 Seconds a value like true or false.
module.js
var PythonShell = require('python-shell');
module.exports = {
switch_live: function(pin) {
var status = false;
this.get = (function(){
return status;
});
var options = {
mode: 'text',
args: [pin],
pythonOptions: ['-u']
};
var pyshell = new PythonShell('./data/switch_loop.py', options);
pyshell.on('message', function(message) {
if (message == 'false') {
if (status) {
// EMIT: button released
}
status = false;
} else {
if (!status) {
// EMIT: button pressed
}
status = true;
}
});
return this.status;
},
some_other_funcs: function(pin) {
// ...
}
}
app.js
var module = require('./module.js');
var button = new module.switch_live(10);
The module can show you the status of the button:
// get status of button
var status = button.get(); // returns "true" or "false"
But I want something like this:
button.on('pressed', function() {
// call this function every time when button is pressed
});
button.on('released', function() {
// call this function every time when button is released
});
Thank you :)
EDIT: I didn't find a solution, because I need the functions inside the "module.exports".
My Solution
It is a module for a Linkerkit-Board.
app.js
var linkerkit = require('./linkerkit.js');
var button = new linkerkit.switch_live(20);
button.on('pressed', function() {
// call this function every time when button is pressed
console.log('press');
});
button.on('released', function() {
// call this function every time when button is released
console.log('release');
});
linkerkit.js
var PythonShell = require('python-shell');
var EventEmitter = require('events');
var util = require('util');
var linkerkit = {
switch_live: function(pin) {
var self = this;
this.status = false;
this.pin = pin;
EventEmitter.call(this);
this.get = function() {
return this.status;
}
this._pyshell = new PythonShell('./data/switch_loop.py', {
mode: 'text',
args: [this.pin],
pythonOptions: ['-u']
});
this._pyshell.on("message", function(message) {
if (message === "false") {
if (this.status === true) {
// EMIT: button released
self.emit("released");
}
this.status = false;
}
else {
if (this.status === false) {
// EMIT: button pressed
self.emit("pressed");
}
this.status = true;
}
});
}
}
for (var key in linkerkit) {
util.inherits(linkerkit[key], EventEmitter);
}
module.exports = linkerkit;
I edited the code because it should be able to do things like that:
var button = linkerkit.switch(20);
button.get() // get status of button once, has no python loop
var button_live = linkerkit.switch_live(20);
button.get() // get status of button once, has a python loop
button.on('pressed', callback);
button.on('released', callback);
var led = linkerkit.led(10);
led.on();
led.off();
led.brightness(255); // digitalOutput - brightness
led.blink(200); // 100ms on, 100ms off
var ledcolor = linkerkit.led_rgb(12);
ledcolor.on(); // on -> color: white
ledcolor.off();
ledcolor.rgb([255, 0, 0]); // on -> color: red
And many more functions...
You should be able to use Node's built-in EventEmitter class to create your own "button emitter":
module.js
var PythonShell = require('python-shell');
var util = require('util');
var EventEmitter = require('events');
function ButtonEmitter(pinNumber) {
this.status = false;
this.pinNumber = pinNumber;
EventEmitter.call(this);
}
util.inherits(ButtonEmitter, EventEmitter);
ButtonEmitter.prototype.get = function() {
return this.status;
};
ButtonEmitter.prototype.switch_live = function() {
var options = {
mode: 'text',
args: [this.pinNumber],
pythonOptions: ['-u']
};
this._pyshell = new PythonShell('./data/switch_loop.py', options);
this._pyshell.on("message", this._handleMessage.bind(this));
return this.status;
};
ButtonEmitter.prototype._handleMessage = function(message) {
if (message === "false") {
if (this.status === true) {
// EMIT: button released
this.emit("pressed");
}
this.status = false;
} else {
if (this.status === false) {
// EMIT: button pressed
this.emit("released");
}
this.status = true;
}
};
module.exports = ButtonEmitter;
app.js
var ButtonTrigger = require('./module.js');
var button = new ButtonTrigger(10);
button.on('pressed', function() {
// call this function every time when button is pressed
});
button.on('released', function() {
// call this function every time when button is released
});
button.swith_live();
Explanation
The above code leverages Node's util.inherits to "subclass" EventEmitter, so that anyone using your class has access to .on(), .off() and other event methods. (Note: you could use ES6 class and extends syntax too, if you're Node version supports it)
Then, using your "subclass", you add your own switch_live method that starts the "listening" process, passing it the _handleMessage callback.
When the _handleMessage callback runs, it will compare the current status to the incoming one, and trigger a .emit() using the event names you posted in your question. Again, the .emit() is available because you a "subclassing" EventEmitter.

onfinish on global soundmanager object

I would like to launch a function at the end of my sound, this code works :
var mysound;
var next = function(){
alert('end');
};
soundManager.onready(function () {
mysound = soundManager.createSound({
id:'foo',
url:'http://soundbible.com/grab.php?id=2077&type=mp3'
})
mysound.play({onfinish:next});
// change to this
// mysound.play();
});
// in another .js
// mysound.onfinish(next) // doesn't work
// mysound.prototype.options.onfinish = next // doesn't work
I would like to do something like I comment.
code on jsfiddle
The problem is that mysound tries to assign the onfinish before it's set to the correct value.
var mysound;
var next = function(){
alert('end');
};
function importedFromOtherFile( mysound ) {
mySound.onfinish(next);
}
soundManager.onready(function () {
mysound = soundManager.createSound({
id:'foo',
url:'http://soundbible.com/grab.php?id=2077&type=mp3'
})
mysound.play({onfinish:next});
// change to this
functionImportedFromOtherFile(mysound);
});
if you want it to be in a different file, see if you can give it a call back or throw an even with mysound after it's set

Emitting custom event

I am using my custom yeoman generator programmatical in one of my nodejs module. I have written an Adapter to replace default TerminalAdapter.
The issues are,
When I am triggering custom event using emit method, I am not able
to listen for that event in my module. It is not getting fired.
Even end event listener also not getting fired.
Please let me know what I am missing here,
Below is my module code,
'use strict';
var fs = require('fs');
var path = require('path');
var MyOwnAdapter = require('./MyOwnAdapter');
var adapt = new MyOwnAdapter();
var env = require('./generator-myframewrk/node_modules/yeoman-generator')(null, {}, adapt);
env.register(path.resolve(__dirname, './generator-myframewrk'), 'myframewrk');
exports.run = function (options, answers) {
var obj = {};
adapt.setAnswers(answers);
process.chdir(options.projdir);
env.on("end", function(){
this.log("Even this is not getting called !!!"); //not coming here
}.bind(this));
env.on("alldone", function(){
this.log("Everything is done (including Bower install)"); //not coming here
obj.cb();
}.bind(this));
env.run('myframewrk', function(){
this.log('ran yo myframewrk, But bower install might be pending'); //coming here
});
return {
done: function (cb) {
obj.cb = cb;
}
};
};
Below is my Generator code,
var MyframewrkGenerator = yeoman.generators.Base.extend({
init: function () {
this.pkg = require('../package.json');
this.on('end', function () {
if (!this.options['skip-install']) {
this._installBower();
}
});
},
_installBower: function () {
this.log("Running bower install...");
/*reads bower.json and installs*/
bower.commands.install([], {}, {directory : "./"}).on('error', function (error) {
this.log("BOWER error::");
this.log(JSON.stringify(error));
}.bind(this)).on('log', function (log) {
this.log("BOWER LOG::"); // coming here
}.bind(this)).on('end', function (installed) {
this.log("BOWER END::"); // coming here
this.emit("alldone"); // my custom event
}.bind(this));
},
askFor: function () { ...
I took _installBower method out of this.on('end', function () {}); and made it a separate async func. This works fine. I don't need custom event anymore!
Thx...
bowerInstallHelper: function(){
if (!this.options['skip-install']) {
var cb = this.async();
this._installBower(cb);
}
}

Functions are undefined

I am trying to create a data management application, but instead of a Windows-based solution or using WebSQL, i am using IndexedDB. I am pretty new to it but I believe I have covered the basis in this draft of code.
Anyway, my problem is, anytime I run the code, my openDB() function and the addeventListener() function both run and show on the console log at runtime but all other functions are said to be undefined when I try to run the code. What could the problem be?
In the HTML file, the jQuery script file is referenced.
(function () {
var DB_NAME = 'shodex';
var DB_VERSION = 1;
var DB_STORE_NAME = 'visitors';
var db;
var current_view_pub_key;
//opens the IndexedDB database
function openDb() {
console.log("open Database......");
var req = indexedDB.open(DB_NAME, DB_VERSION);
req.onsuccess = function (evt) {
db = this.result;
console.log("Database Opened");
};
req.onerror = function (evt) {
console.error("openDb:", evt.target.errorCode);
};
req.onupgradeneeded = function (evt) {
console.log("Event fired when DB is needed to be upgraded");
var store = evt.currentTarget.result.createObjectStore(
DB_STORE_NAME, { keyPath: 'id', autoIncrement: true });
store.createIndex('name', 'name', { unique: false });
store.createIndex('date', 'date', { unique: false });
store.createIndex('whom_to_see', 'whom_to_see', { unique: false });
store.createIndex('arrival_time', 'arrival_time', { unique: false });
store.createIndex('reason', 'reason', { unique: false });
store.createIndex('departure_time', 'departure_time', { unique: false });
};
}
//used to create a transaction
function getObjectStore(store_name, mode) {
var tx = db.transaction(store_name, mode);
return tx.objectStore(store_name);
}
//adds a Visitor to the IndexedDB
function addVisitor(name, date, to_see, arrival_time, reason, departure_time) {
console.log("Adding the following data to IndexedDB: ", arguments);
var obj = { name: name, date: date, whom_to_see: to_see, arrival_time: arrival_time, reason: reason, departure_time: departure_time };
if(typeof blob != undefined)
{
obj.blob = blob;
}
var store = getObjectStore(DB_STORE_NAME, 'readwrite');
var req;
try
{
req = store.add(obj);
}
catch(e)
{
if(e.name == 'DataCloneError')
displayActionFailure("This engine does not know how to clone a Blob, use Firefox!");
throw(e);
}
req.onsuccess = function (evt) {
console.log("Insertion into DB was successful. You can heave a huge sigh of relief!");
displayActionSuccess();
};
req.onerror = function () {
console.error("Insertion into DB failed!");
displayActionFailure(this.error);
};
}
function displayActionSuccess() {
alert("Whatever the heck you were doing was successful. Congrats!");
}
function displayActionFailure() {
alert("Oh Oh! System Failure! System Failure!");
}
// listens for the submit button event
function addEventListeners() {
console.log("Event Listeners");
$('#addVisitor').click(function(evt) {
console.log("Add Visitors Submit button");
var name = document.getElementsByName("txtName").value;
var date = document.getElementsByName("txtDate").value;
var whom_to_see = document.getElementsByName("txtToSee").value;
var time_of_arrival = document.getElementsByName("txtArrivalTime").value;
var reason_for_visit = document.getElementsByName("txtReason").value;
var time_of_departure = document.getElementsByName("timeOfDep");
addVisitor(name, date, whom_to_see, time_of_arrival, reason_for_visit, time_of_departure);
});
}
//makes the database open at runtime
openDb();
addEventListeners();
})
();
syntax error - you need a closing round bracket at end.
i.e add
);
I think the problem is the fact that when your anonymous function is run the browser doesn't not know about the '#addVisitor' element, so the click event handler for that element is not created.
You should put your code inside "$(function() {" or "$(document).ready(function() {":
$(function() {
(function () {
var DB_NAME = 'shodex';
var DB_VERSION = 1;
...
Instead of referencing the javascript code like before...
I removed all other functions from the javascript file leaving the openDB() function and placed them in the main html file. it worked automatically.

Categories

Resources