gameFrenzy07
gameFrenzy07

Reputation: 397

Example script provided by neo4j for JavaScript won't run

I am very new to the graph database ecosystem and for start I am experimenting with the neo4j. I would very much like to work with node and neo4j. So after a quick search I found neo4j-driver that is an officially supported driver for JavaScript and an example provided which is:

const neo4j = require('neo4j-driver')

const driver = neo4j.driver(uri, neo4j.auth.basic(user, password))
const session = driver.session()
const personName = 'Alice'

try {
  const result = await session.run(
    'CREATE (a:Person {name: $name}) RETURN a',
    { name: personName }
  )

  const singleRecord = result.records[0]
  const node = singleRecord.get(0)

  console.log(node.properties.name)
} finally {
  await session.close()
}

// on application exit:
await driver.close()

now when I run this code, I immediately get the following error:

SyntaxError: await is only valid in async function

Now I thought I understood the error that I would have to wrap the try-catch block with anonymous async function to get rid of the error. The changed code body is:

const config = {
    "neo4j": {
        "url": "neo4j://localhost",
        "authUser": "neo4j",
        "authKey": "adminPassword"
    }
}

const neo4j = require("neo4j-driver");

const driver = neo4j.driver(
    config.neo4j.url,
    neo4j.auth.basic(config.neo4j.authUser, config.neo4j.authKey)
);

const session = driver.session();

(async () => {
    try {
        const result = await session.run('CREATE (a:Person {name: $name}) RETURN a', { name: 'Alice' });

        const singleRecord = result.records[0];
        const node = singleRecord.get(0);

        console.log(node.properties.name);
    } catch (error) {
        console.log("Error Body: ", error);
    } finally {
        await session.close();
    }
})();

await driver.close();

But to my dismay, I have run into another error that is very cryptic:

{ Neo4jError: Could not perform discovery. No routing servers available. Known routing table: RoutingTable[database=Sample database, expirationTime=0, currentTime=1592397056399, routers=[], readers=[], writers=[]]

    at captureStacktrace (/Users/pc/node_modules/neo4j-driver/lib/result.js:263:15)
    at new Result (/Users/pc/node_modules/neo4j-driver/lib/result.js:68:19)
    at Session._run (/Users/pc/node_modules/neo4j-driver/lib/session.js:174:14)
    at Session.run (/Users/pc/node_modules/neo4j-driver/lib/session.js:135:19)
    at /Users/pc/neoNode.js:20:38
    at Object.<anonymous> (/Users/pc/neoNode.js:31:3)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12) code: 'ServiceUnavailable', name: 'Neo4jError' }

Upvotes: 1

Views: 1598

Answers (2)

Kebman
Kebman

Reputation: 2079

I also had some problems with this.

First off, Natam Oliveira is correct. You need to use the bolt protocol, and await promises needs to be within an async function. For some reason the neo4j protocol is used in some examples in the docs. Additionally it would seem both examples currently provided by Neo4j—in the driver-manual and javascript-driver section—causes errors if you use them outside of some kind of unspecified environment.

There were some clues on the npmjs pagckage page, though, so by working them into the existing code, I was at least able to spit out some data. However I'm also wondering on how you could make this work inside the async function, so an explanation to how that could work with this driver would be very welcome.

Here's what worked for me:

const neo4j = require('neo4j-driver')

const cnx = {
    user: 'neo4j',
    password: 'some passphrase',
    uri: 'bolt://localhost:7687'
}

const driver = neo4j.driver(cnx.uri, neo4j.auth.basic(cnx.user, cnx.password))

driver.verifyConnectivity()
    .then((cnxMsg) => {
        console.log(cnxMsg)
    })

const session = driver.session({ database: 'neo4j' })

session.run('MATCH (n:Movie) RETURN n LIMIT 5')
    .subscribe({
        onKeys: keys => {
            console.log(keys)
        },
        onNext: record => {
            console.log(record.get('n').properties.title)
        },
        onCompleted: () => {
            session.close()
        },
        onError: error => {
            console.error(error) 
        }
    })

This spits out some movies using the streaming API as seen in the NPM documentation. (Note: It will only work if you started/installed the Movie database, so double check that you didn't delete it, as its deletion is also part of the Neo4j tutorial.) Now just change the MATCH Cypher query to whatever you like, and play around with the output, for instance by piping it to Express.

Sources:

Upvotes: 2

Natam Oliveira
Natam Oliveira

Reputation: 34

first of all, I think your URL should be "url": "bolt://localhost:7687" And you still with await driver.close() outside an async function

If you are starting to use neo4j, look for an OGM (Object Graph Model) to help you.

Upvotes: 0

Related Questions