Object #<Object> has no method 'http' when using neo4j and bluebird

156 Views Asked by At

I am using this Neo4J library and I would like to use promises instead. So I tried using bluebird's promisify. I created the following code...

    var db = new neo4j.GraphDatabase('....'),
        Promise = require('bluebird'),
        Cypher = Promise.promisify(db.cypher);

    var query = [
        'MATCH (node)',
        'OPTIONAL MATCH (node)-[rel]->( )',
        'RETURN DISTINCT node as node, collect(rel) as links'
    ].join('\n');

    var i = 0
    var onSuccess = function (results) {
            res.json(parseGraphResponse(results));
        },
        onFail = function (err) {
            console.log("Error " + err);
        };
    Cypher({
        query: query
    }).then(onSuccess).catch(onFail);

However, now I get the following error that is captured onError...

TypeError: Object # has no method 'http'

This version works fine...

    db.cypher({
        query: query
    }, function (err, results) {
        if (err) {
            console.log("Error " + err);
            return;
        }
        res.json(parseGraphResponse(results));
    });

A little more investigation shows that it is blowing up on this code...

GraphDatabase.prototype.cypher = function(opts, cb, _tx) {
  ...
  // Blows up here....
  return this.http({
        method: method,
        path: path,
        headers: headers,
        body: body,
        raw: true
      }, (function(_this) {
        return function(err, resp) {
          ...
        }
      })
}
2

There are 2 best solutions below

2
On BEST ANSWER

I bet this will fix it:

Cypher = Promise.promisify(db.cypher.bind(db));

For future reference, the way to debug this is to interpret the error message as saying that this doesn't have an http method, but you know db does, so this must not be set to db. And indeed, passing db.cypher loses the this reference to db.

0
On

In addition to the answer I would recommend adding the following...

if(db.cypher)
  Promise.promisify(db.cypher.bind(db));

the if will prevent failure if the DB is down. In my case I use an XML file to mock data when I can't reach the server.