while reading the node-mysql documantation i saw a usage as i pasted below
var query = connection.query('SELECT * FROM posts');
query
.on('error', function(err) {
// Handle error, an 'end' event will be emitted after this as well
})
.on('fields', function(fields) {
// the field packets for the rows to follow
})
.on('result', function(row) {
// Pausing the connnection is useful if your processing involves I/O
connection.pause();
processRow(row, function() {
connection.resume();
});
})
.on('end', function() {
// all rows have been received
});
i wonder how they use this events those can be used with the name whatever
user names the query query in example when i create custom events i name them first for example var foo=new events.EventEmitter and after this in whole page i have to use it as foo.on("someEvent")
but here they somehow bind the var created by user as event name in example code user names the mysql query as query and the event emitter has the same name somehow
and second question how is that possible to chain events as they use
.on("event").on("anotherEvent")
this question may sound strange but i really wonder how this works and it will change my code design completely
query is just your variable name for what is an instance of a Query in the node-mysql lib. You get access to all the functions that object exports.
on is inherited from EventEmitter in the node.js core. The key thing is that calling on returns "itself" i.e. this:
Returns emitter, so calls can be chained.
This allows you to chain calls to on
Related
I'm using the Node.js net package to connect to and communicate with a Telnet server. I'm using net.createConnection() to create and initialize a socket; then doing something like the following to bind the initial data event listener:
client.on('data', (data) => { this.handleFoo(data) });
I thought it might be a good idea to encapsulate different functionality in different callbacks; one to handle negotiating the connection, logging in, etc. One for general purpose communication.
I tried simply calling .on() again to see if I could replace the event listener callback to something that didn't have all of the connection/logon code:
client.on('data', (data) => { this.handleBar(data) });
Unfortunately that had no effect, and the original callback was getting called again. Is this possible to do?
I couldn't find another socket method that would un-register that first listener callback.
Thanks.
You need a named function. Use client.removeListener() or client.off() available since Node.js v10.0.0. These are available to net.Socket because it extends EventEmitter.
const fooHandler = (data) => { this.handleFoo(data) };
client.on('data', fooHandler);
...
client.off('data', fooHandler);
Apologies if this is a duplicate, I searched the internet for hours and came up empty so I decided to post here.
I am developing a module for node.js that would have to deal with socket connections. I want to create a function that returns an object to the user that will then receive events the user can set listeners on. However, I want to do it in a way so that the user wont be able to emit events on that object. Instead, I want the emit function in my event emitter to be overwritten by my own function.
Basically, I want to return an object that receives events and has a function called "emit" that acts like any regular function.
Heres a small example of what I have in mind:
var events = require('events');
var out = (function(){
var obj = new events.EventEmitter();
// I used nextTick to emulate the asyncrounes nature of the socket server
process.nextTick(function(){
obj.emit('Message', "Dummy socket message") // This will be triggered when a message is sent to the socket server
})
return obj;
})();
out.on('Message', function(msg){
console.log(msg)
out.emit("newWork", "New instructions")
// Im trying to make it work so that this would not throw the event emitter into an infinite loop
});
Now, in the out.on("Message", function... part I want the user to be able to write out.emit("dummy", "dummy data") and be able to call my own emit function that does something with the provided inputs.
How would I go about doing that?
I know it must be possible somehow since socket.io does exactly that.
Heres a small piece of code with socket.io
socket.on('test', function(){
console.log("called!")
})
socket.emit("test")
When I run that, it doesnt trigger itself. The emit function seems to be overwritten by something else but the socket object still receives events that are emitted from within somehow.
I hope that my explanation was sufficient.
Thanks in advance!
Edit: I know that using (function() { ... })() is not the way to create modules. Im using here just to make it easier to illustrate as the concept stays the same with this approach
I think I figured it out on my own.
I will overwrite the emit function in the new EventEmitter instance that I create with my own function and use the one from EventEmitter.prototype instead. That way I can ship my object back to the user with a custom emit function while still being able to emit events on that object from my module
Here's a small demo I wrote while trying to figure this out.
var events = require('events').EventEmitter;
obj = new events();
obj.emit = function(name, data){
console.log("Received: name - " + name + "; data - " + data);
}
function emitOnObj(obj, name, msg){
events.prototype.emit.call(obj, name, msg);
}
This looks pretty good to me but if there's a better way to do this then Im all ears :)
I use parse.comas backend service for my iOSapp. I was trying to do everything in objective-c since I don't have any experience with JavaScript, but turns out I will need to develop some Cloud Code Functions in JavaScript to complete my app.
A simple routine I'm trying to create:
User retrieves an object using a Cloud Function.
User saves another object in a different class.
An afterSavefunction runs in the cloud to update object first retrieved.
Now, here is my code:
var UserConfigOrientador = Parse.Object.extend("UserConfigOrientador");
var query = new Parse.Query(UserConfigOrientador);
Parse.Cloud.define('pegarOrientadorLivre', function(request, response) {
Parse.Cloud.useMasterKey();
query.greaterThan("entrevistasDisponibilidade", 0);
query.first({
success: function(results) {
response.success(results);
query = results;
},
error: function(error) {
response.error('Favor, checar rede e tentar novamente.');
}
});
});
// AfterSave
Parse.Cloud.afterSave("Agenda", function(request) {
Parse.Cloud.useMasterKey();
query.set("entrevistasDisponibilidade", 70);
query.save();
}
});
});
Now, the second function is not working, I'm getting the message that Object has no set method.
Basically, my questions are:
How can I share data between functions?
Should I keep everything in main.js or can I use another file?
I'm using webStorm for development. And the question about main.js is that after a while I will have a lot of functions and I am trying to figure out how to organize my code.
Your issue is one of scope, and poorly named variables that you're reusing for multiple purposes.
You define your query variable as a query, use it, but inside the success handler you set it to the result of the query (you now have a variable called query which is actually an instance of your UserConfigOrientador class).
When that Cloud Code finishes running, the result goes out of scope and is most likely set to undefined. You shouldn't be trying to share variables between multiple Cloud Code methods like that.
Is there something on the Agenda object that can let you know which UserConfigOrientador to update? Perhaps you could add a pointer property to the UserConfigOrientador? If you did, then you could use the following:
// AfterSave
Parse.Cloud.afterSave("Agenda", function(request) {
Parse.Cloud.useMasterKey();
var userConfigOrientadorQuery = new Parse.Query("UserConfigOrientador");
// read "userConfigOrientador" pointer property on "Agenda" object
var userConfigId = request.object.get("userConfigOrientador").id;
userConfigOrientadorQuery.get(userConfigId, {
success: function(userConfigOrientador) {
userConfigOrientador.set("entrevistasDisponibilidade", 70);
userConfigOrientador.save();
}
});
});
Mm.. I don't think it quite works the way you expect.
When your Cloud code runs, your initial var query declaration is indeed available within the scope of your cloud function and afterSave function. However, you're not passing it in correctly. As a matter of fact, I'm a little confused because your query seems to be requesting a UserConfigOrientador object while your afterSave is on an Agenda object.
So there are two different things going on here. Since you don't actually save an agenda object, I'm assuming that your response.success() returns a JSON of the UserConfigOrientador object back to client side at which point you do some manipulation then save the Agenda object based on that result.
At this point, when you save() the Agenda object now the afterSave() function will run but your query value will be the var query = new Parse.Query(UserConfigOrientador); which does not have a set method. This is why you get the error.
I'm not even sure your query = results; line will actually execute as you should be calling it at the END of your sub-routine and it signals to Parse that it is the end.
If you can tell me how you're saving the Agenda object I can probably complete the picture.
EDIT: --- abstracted but maybe this is the pattern you're looking for...
var ObjectA = Parse.Object.extend('ObjectA');
var queryObjectA = new Parse.Query('ObjectA');
Parse.Cloud.define('findObjectX', function(request, response) {
Parse.Cloud.useMasterKey();
// other query options here...
query.first({
// the first() function will return a Parse.Object
success: function(objectX) {
// Now you have objectX
// Now you want to save some other object
var otherObj = new ObjectA();
// Do things to otherObj
otherObj.save({
success: function(result) { // will be the saved otherObj
// Now you do stuff to your queried obj and save
objectX.set('something', result); // or whatever
// Note, it accomplishes what I think you want without afterSave()
}
}); // async... but we can just let this guy go
},
error: function(error) {
response.error('Favor, checar rede e tentar novamente.');
}
});
});
I have a simple function which routes a HTTP query pattern, queries redis and sends a response. The following is the code
router.get('/getinfo/:teamname', function main(teamname) {
rclient.hgetall(teamname,function(err,obj){
console.log("the response from redis is ",obj)
cache.put(eventname,obj);
console.log("inserting to cache");
this.res.end(obj); // this object is root cause for all problems
});
}
The router object afaik, sends the response using this.res.end(obj) . I guess since I am trying to do this inside my redis client , I am getting error. Is there any other way to send the value as a response ? I thought of using emitter based model where the channel emits the response and listener gets it. but it feels like a round about way to solving this problem. Is there any simpler approach ?
The error may be because, where you're trying to use this, it doesn't have the intended value -- an object with a res property that in turn has an end() method.
That would be because every function in JavaScript has its own this with its own value. And, when nesting functions, using this will return the value for the closest function (i.e. shadowing).
To resolve that, you can save the intended value to a local variable:
router.get('/getinfo/:teamname', function main(teamname) {
var request = this;
rclient.hgetall(teamname,function(err,obj){
// ...
request.res.end(obj);
});
});
Or, bind the anonymous callback so both functions are forced to have the same this value:
router.get('/getinfo/:teamname', function main(teamname) {
rclient.hgetall(teamname, function(err,obj){
// ...
this.res.end(obj);
}.bind(this));
});
I'm very new to Node.js and I'm just trying to make sense of how the parameters work in the callback methods of the code.
I can only understand the first one, function(req,res), because I've used that in Java when working server-side, but I don't really understand how it automatically calls the memcached function or how that kicks off the rest, etc. If somebody could explain to me how this works I'd really appreciate it. Thank you
server.on('request', function(req, res) {
//get session information from memcached
memcached.getSession(req, function(session) {
//get information from db
db.get(session.user, function(userData) {
//some other web service call
ws.get(req, function(wsData) {
//render page
page = pageRender(req, session, userData, wsData);
//output the response
res.write(page);
});
});
});
});
It could roughly be compared to passing the anonymous class in Java. For example to sort a collection in Java you pass a comparator class which has a method for comparing two objects. Later, when sorting algorithms needs to compare the objects it calls the function in provided class.
In javascript functions are first class objects, which means we don't need a "wrapper" class and can pass it as a parameter to another function.
In your case "memcached.getSession" will execute is't logic, find the session, and calls the anonymous function you pass in the second parameter, with the session as parameter.