I am using the ROS JavaScript Library (CDN) which uses EventEmitter2 (CDN) to listen to a topic. Please see the following code snippet:
var ros = new ROSLIB.Ros({ url: "ws://localhost:9090" });
class Subscriber extends EventEmitter2 {
constructor(element) {
super();
this.element = element;
this.listener = new ROSLIB.Topic({
ros: ros,
name: "/listener",
messageType: "std_msgs/String",
});
this.listener.subscribe(this.handleCallback);
}
handleCallback(message) {
this.emit("update", message.data, this.element);
// just for debugging. access a property of our element
console.log("callback" + message.data + " " + this.element.innerHTML);
}
}
Upon receiving a message, an event is fired which is handled by the handleCallback. Here, using console.log("callback" + message.data), the message (string) is visible.
My goal is to receive the new callback as shown below:
var element = document.getElementById("hello");
var subscriber = new Subscriber(element);
subscriber.on("update", (data, element) => {
console.log("received" + data + " " + element.innerHTML);
});
However, there are two problems mentioned below:
Accessing the element using this.element is throwing the following error:
Uncaught TypeError: Cannot read properties of undefined (reading 'innerHTML')
To avoid the above error temporarily, I removed it from the emit call as this.emit("update", message.data) but no success. Furthermore, I used this.emit("update", "my static message") but didn't receive a callback.
Related
As the title suggests, I am trying to use promiseToFuture (function of the dart library dart:js_util) on an object deriving from the method of DART:JS which is context.callmethod (''), whose objective is to perform a JavaScript function, which identifies through the string passed as a parameter; The code below:
void onWalletConnect() {
var promiseWallet =
await promiseToFuture(js.context.callMethod('JsConnectWallet'));
// ignore: avoid_print
print(promiseWallet);
if (promiseWallet['address'].compareTo('errorAddress') != 0) {
setState(() {
walletAddress = promiseWallet['address'];
isWalletconnect = true;
});
}
}
// "`js.context.callMethod('..')` Returns an Object Promise; "
Below the import:
import 'dart:js' as js;
import 'dart:js_util';
To the execution of promisetofutures() [and I am sure that this is the function that generates error and not the js.context.callMethod()] I get the following error from the Chrome console:
"
Uncaught (in promise) TypeError: js.Promise.then in not a function
at Object.promiseToFuture (js_util.dart:275:35)
at _first._MyHomePageState.new.OnWalletConnect (_first.dart:28:1)
"
I don't understand why you generate this error and how to solve it, can anyone help me?
I program usually in python and I am trying something that usually works in python. I have a function in a class. Its a callback function of mqtt library. What I want is to save the message(in a function onMessageArrived) that I receive into class variable called (this.)buffer.
class sub{
constructor(hostname,port,clientid,topic){
this.buffer = [];
this.hostname=hostname;
this.port=port;
this.clientid = clientid;
this.topic = topic;
this.client = new Paho.MQTT.Client(hostname,port, clientid);
// set callback handlers
this.client.onConnectionLost = this.onConnectionLost;
this.client.onMessageArrived = this.onMessageArrived; <----Problem
// connect the client
this.client.connect({onSuccess:this.onConnect});
}
onConnect(){
console.log('OnConnect');
}
onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:"+responseObject.errorMessage);
}
}
onMessageArrived(message) {
console.log("onMessageArrived:"+message.payloadString);
this.buffer.push(message.payloadString) <-------------Problem
}
subs(){
this.client.subscribe(this.topic)
}
publ(message){
var mg = new Paho.MQTT.Message(message);
mg.destinationName = this.topic;
this.client.send(mg);
}
}
Problem is that function onMessageArrived doesnt push message into this.buffer variable-it looks like the function has no idea its inside class and therefore I cannot access class variable through 'this.'. In python it works this way. I am quite desperate because I looks to me like that function is totaly isolated and there is no other way than just print the message.
the error:
onConnectionLost:AMQJS0005E Internal error. Error Message: Cannot read
property 'push' of undefined, Stack trace: TypeError: Cannot read property
'push' of undefined
Thanks in advance
I have created a dictionary and inserted values to it as shown below using https://github.com/basarat/typescript-collections#a-sample-on-dictionary.
private subscribedTopicsDict = new collections.Dictionary<string, MyTopic>();
this.subscribedTopicsDict.setValue(topic, myTopic);
When I print the value for the key "myTopic" immediately after setting, its gets printed. But when I call it inside a callback within the constructor, nothing is happening. No errors but nothing after the getValue line is getting executed. Below is how I am calling it.
constructor(url: string, mqttOptions: MqttOptions, messageReceivedCallBack: IMessageReceivedCallBack) {
if (!_.isString(url) || _.isEmpty(mqttOptions || _.isEmpty(messageReceivedCallBack))) {
throw new MyError('invalid url value');
} else {
this.client = mqtt.connect(url, mqttOptions);
this.client.on('message', (topic: string, message: string) => {
let myMessage: myMessage;
let receivedTopic: myTopic;
console.log('1.onMessageReceived called with topic : ' + topic);
receivedTopic = this.subscribedTopicsDict.getValue(topic);
console.log('2.received topic and dataTypeID' + receivedTopic.dataTypeID);
myMessage = {
myTopic: receivedTopic,
payload: message
};
console.log('about to fire the callback');
messageReceivedCallBack.onMessageReceived(myMessage);
});
}
}
The second console log is not getting printed. I tried with default dictionary functionalities of type script and got the same behavior as well.
I'm using Tizen's Wearable SDK to create a watch face, and while I am able to retrieve the Bluetooth's power state by using blueAdapter = tizen.bluetooth.getDefaultAdapter(); and bluetoothPowered = blueAdapter.powered;, I'd rather use a Bluetooth listener instead of constantly calling blueAdapter.powered.
The problem I'm having is that although I did a straight forward copy and paste of the sample code (although I did change the adapter's name, see below) from Tizen's Bluetooth API webpage, I'm getting the following error: 'undefined' is not a function (evaluating 'blueAdapter.setChangeListener(changeListener)').
This is the code I am using:
var blueAdapter = tizen.bluetooth.getDefaultAdapter();
var changeListener = {
onstatechanged: function(powered) {
console.log ("Power state is changed into: " + powered);
},
onnamechanged: function( name) {
console.log("Name is changed to: " + name);
},
onvisibilitychanged: function(visible) {
console.log("Visibility is changed into: " + visible);
}
};
blueAdapter.setChangeListener(changeListener);
Not sure if it helps, but I am using the following the privileges:
http://tizen.org/privilege/bluetooth.admin
http://tizen.org/privilege/bluetooth.gap
Any help would be appreciated.
Although it's been a while now, have you tried changing the syntax like below?
function changeListener(handler) {
handler.onstatechanged = function(powered) {
console.log ("Power state is changed into: " + powered);
}
handler.onnamechanged = function(name) {
console.log("Name is changed to: " + name);
}
handler.onvisibilitychanged = function(visible) {
console.log("Visibility is changed into: " + visible);
}
};
this replaces your listener object by a function, which should then declare the needed functions in the listener. It is just an idea, i did not test it yet.
I want to log objects using log4javascript. For example consider the following code:
function LogObject() {
var blah = {
one: 42,
two: "486"
};
logger.Info(blah);
Assuming that logger is instance of log4javascript logger that is properly set up:
var logger = log4javascript.getLogger("InternalLogger");
var ajaxAppender = new log4javascript.AjaxAppender(url),
jsonLayout = new log4javascript.JsonLayout(false, false);
ajaxAppender.setLayout(jsonLayout);
ajaxAppender.addHeader("Content-Type", "application/json");
logger.addAppender(ajaxAppender);
I am expecting the result to the following: request payload contains array of messages first of which is my object serialized into JSON. What I see is array of messages first of which has string "Object object" (like toString() method was invoked). How can I achieve that?
JsonLayout formats the logging event (which includes log level, timestamp and logger name in addition to the log message(s)) as JSON rather than the log message, which is pretty much assumed to be a string. The reason for this is to avoid a dependency on a JSON library for older browsers; generating JSON for the simple, known data that JsonLayout deals with is no problem without a JSON library but handling arbitrary objects definitely requires one.
The workaround I'd suggest is simply to format the message before you pass it to the logging call:
logger.info( JSON.stringify(blah) );
We were following #Tim Down's suggestion
logger.info( JSON.stringify(blah) );
But we had performance issues since the JSON.stringify happens before logger.info is called, therefore it will always happen even if the logging level is set to ignore this log.
In order to work around this I wrote a new lazy layout so that the stringification only happens if the log is actually output. In order to be more flexible it also alows passing a function, in which case it outputs the result of running said function.
Usage:
logger.trace("Received ", widget, " which has ", () => countFrimbles(widget), ' frimbles');
Implementation:
function LazyFormatLayout() { }
LazyFormatLayout.prototype = new log4javascript.Layout();
LazyFormatLayout.prototype.format = function (loggingEvent) {
var time = loggingEvent.timeStamp.toTimeString().split(/\s/)[0];
var head = time + ' ' + loggingEvent.logger.name + ' [' + loggingEvent.level.name + '] - ';
var body = loggingEvent.messages.map(function (arg) {
try {
switch (typeof (arg)) {
case 'function':
return arg();
case 'object':
return JSON.stringify(arg);
}
}
catch (e) {
return '<<error while logging: ' + e.stack + '>>';
}
return arg;
}).join('');
if (!loggingEvent.exception)
return head + body;
return head + body + ' ==> Exception: ' + loggingEvent.exception.stack;
}
LazyFormatLayout.prototype.ignoresThrowable = function () { return false; };
LazyFormatLayout.prototype.toString = function () { return "LazyFormatLayout"; };
Question is somewhat dated, but a simple google search turned up this question and there seems to be a build-in way to log objects:
var log = log4javascript.getDefaultLogger();
log.info("log following object",{ data:5, text:"bla" });
output
12:49:43 INFO - log following object {
data: 5,
text: bla
}