Coming from the Java Programming Language where all information that can be used in a method must either be part of a class, or passed by parameter, I'm very confused on to where JavaScript magically generates it's very important data.
In this case I'm using Socket.IO and trying to call a login-method after connection, now I could just use an anonymous function, but I personally believe they're really ugly.
Here's my code:
socketIO.sockets.on('connection', function(socket) {
console.log("Connection maid.");
socket.on('login', login);
});
function login(json) {
sqlConnection.query('select * FROM Accounts', function(err, rows, fields) {
if(err) throw err;
for(var row in rows) {
if(rows[row].Username == json.username) {
console.log("Exists");
socket.emit('login', {nuel: ''});
}
}
});
}
As you can see the login function is called whenever the socket receives a login message, and the json object is magically passed to it. I have no idea where it comes from or what generates it, nor do I have a clue how to pass additional arguments to the method, because it breaks/overwrites the magic data.
The error I'm running into is where socket doesn't exist in the current context, because it was not passed to the login function, however when I try to pass it, the object saved as json is completely eradicated from existence.... AND WHERE IS THE DATA THAT'S HERE COMING FROM.
I don't understand this at all, How can I pass this information to call the method, without completely breaking everything.
Related
I'm requesting the blueprint route User.findOne in SailsJs on the basis of user Id but it itself is calling User.update. Also, I just experienced a new thing that on sending multiple parameters to findOne, it updates the record on the basis of any single matched parameter. On the other hand, If i do create a controller named user.findOne and call the same route via controller, it works perfectly fine.
Is that the right behavior by SailsJs or I'm doing some mistake anywhere?
I have the same issue, still wondering why is this happening,
I even tried creating an update function in my controller with some sample code but when I try hitting findOne from postman, it redirects me to my created update function.
Waiting for an answer on this serious issue.
However I found a solution by trying something like this (i.e. creating custom findOne function in the controller) and it worked:
findOne : function (req,res){
var myReq = req.params.all();
console.log(myReq);
User.findOne(myReq, function UserFound(err, user){
if (err) return res.negotiate("User not found!");
else{
console.log("I am getting here");
console.log(user);
return res.status(200).send(user);
}
})
}
I have a script updating a MongoDB collection and log the error and result object in its callback function. Every works fine except the result object contains a long chunk of code, which I have no idea how to get rid of. I'm using native MongoDB node.js driver, version 2.0.46.
Code snippet:
var find = {_id:id}, set = {$set:{dt:now}};
myCollection.update(find, set, function(err, result) {
if(err) logger.error(JSON.stringify([find, set]), err.toString());
else logger.verbose(result);
})
I then receive this set of log entry when no error occurs for the update.
2015-10-29T03:45:13.253Z - verbose: ok=1, nModified=1, n=1, _bsontype=Timestamp, low_=17, high_=1446090311, _bsontype=ObjectID, id=V.ßÂb$#\¾¾«, domain=null,
close=function g() {
this.removeListener(type, g);
if (!fired) {
fired = true;
listener.apply(this, arguments);
}
The function you see in the log entry above is just a small part. The actual "close function" is tens of thousands lines long, so it fills up my log files quickly.
The logger I'm using is Winston.
I'm wondering what I have done wrong to cause such a return? Any advice is appreciated.
This is not mongodb or native mongodb driver issue.
MongoDB result contains the other details regarding database and row so you are receiving the method in the console.
You need to log the information which you need by accessing the objects available in result object i.e result.ok, result.n, result.nModified
something like below,
winston.info(result.ok, result.n, result.nModified);
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'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.
Coming from a c# background, I'm probably looking at JavaScript from a completely wrong perspective, so please bear with me.
Leaving the advantages of async aside for a minute,
let's say I simply want to retreive a value from an SQLite database in an HTML5 page.
What I want to see is something like
var something = db.getPicture(1);
Now consider a (perhaps very naive) implementation of this:
this.getPicture(id)
{
this.database.transaction(function(tx)
{
tx.executeSql('SELECT ......', null, function(tx, results)
{
if (results.rows.length == 1)
return results.rows.items(0).Url; //This of course does not resturn
//anything to the caller of .getPicture(id)
}
},
function(error)
{
//do some error handling
},
function(tx)
{
//no error
});
}
First off, it's one big mess of nested functions and second... there's no way for me to return the result I got from the database as the value of the .getPicture() function.
And this is the easy version, what if I wanted to retreive an index from a table first,
then use that index in the next query and so on...
Is this normal for JavaScript developers, am I doing it completely wrong, is there a solution, etc...
The basic pattern to follow in JavaScript (in asynchronous environments like a web browser or Node.js) is that the work you need to do when an operation is finished should happen in the "success" callback that the API provides. In your case, that'd be the function passed in to your "executeSql()" method.
this.getPicture = function(id, whenFinished)
{
this.database.transaction(function(tx)
{
tx.executeSql('SELECT ......', null, function(tx, results)
{
if (results.rows.length == 1)
whenFinished(results.rows.items(0).Url);
}
},
In that setup, the result of the database operation is passed as a parameter to the function provided when "getPicture()" was invoked.
Because JavaScript functions form closures, they have access to the local variables in the calling context. That is, the function you pass in to "getPicture()" as the "whenFinished" parameters will have access to the local variables that were live at the point "getPicture()" is called.