I'm a self taught novice programmer working on a simple web application that uses Angular.js, Node.js, and the graph database neo4j. Right now I'm trying to get a a very basic query to execute and return data to the client. Upon execution I get an error which closes the server.
The following function is executed upon receiving a get request:
exports.test = function (req, res) {
var neo4j = require('neo4j');
var db = new neo4j.GraphDatabase('http://localhost:7474');
var query = [
'MATCH n',
'RETURN n.name, n, labels(n)'
];
db.query(query, function (err, results) {
if (err) {throw err};
var data = results.map(function(result) {
return result;
});
res.send(data)
}
)};
I get the following error in the console log: java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.String
(I can provide the entire log if it would prove useful)
I would be extremely grateful for any insights.
The reason for your error is that you're passing an array as a query:
var query = [
'MATCH n',
'RETURN n.name, n, labels(n)'
];
db.query(query, function (err, results) { ... }
That should be a string, hence the java.lang.ClassCastException.
So you should either join the query array to make it a string, or don't use an array:
// solution 1
var query = [
'MATCH n',
'RETURN n.name, n, labels(n)'
].join(' ');
// solution 2
var query = 'MATCH n RETURN n.name, labels(n)';
Also, this code is a bit superfluous:
var data = results.map(function(result) {
return result;
});
res.send(data);
Why not use this?
res.send(results);
There actually is no issue. It's how Node.js works. Node.js is actually an asynchronous language, meaning that it will execute the next statement WITHOUT waiting for the previous statement to be fully executed. Currently, your code works on the assumption that the variable data will be defined before it is used with res.send(). However, this is NOT the case. What is actually happening is this:
data is NOT yet defined.data, which doesn't yet exist.data variable is defined with the callback in your results.map().This is how the asynchronous behavior of NodeJS works. Basically, callbacks (functions within methods) execute LAST. Thus, you would want to put the res.send() statement in your callback, like so (note that defining the data variable is useless in the first place since it depends on a callback for its value):
results.map(function(result) {
res.send(result);
});
It is a tough concept to wrap your head around...took me about a week. Let me know if you have any more questions.