Neo4j-graphql-js: Cannot create custom resolvers without @relation

Created on 16 Jul 2019  路  6Comments  路  Source: neo4j-graphql/neo4j-graphql-js

I am making a photo gallery site, and photo urls are generated on the server and not managed by the neo4j database.

This is currently my typedefs:

type PhotoURL {
  thumbnail: String
  original: String
}

type Photo {
  id: ID!
  title: String
  path: String!
  url: PhotoURL @relation(name: "NOTHING", direction: "IN")
}

I have a custom resolver for the url field on for the Photo type.
But it throws an error if I remove the dummy relationship @relation(name: "NOTHING", direction: "IN"), even though I have a custom resolver defined.

It would probably be better, if the field was ignored when a custom resolver is defined, instead of throwing an error.

Stack-trace for error if relationship is removed

TypeError: Cannot read property '0' of undefined",
            at buildCypherSelection (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/selections.js:321:20)
            at recurse (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/selections.js:83:33)
            at buildCypherSelection (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/selections.js:181:12)
            at recurse (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/selections.js:83:33)
            at buildCypherSelection (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/selections.js:206:22)
            at recurse (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/selections.js:83:33)
            at buildCypherSelection (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/selections.js:181:12)
            at nodeQuery (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/translate.js:584:69)
            at translateQuery (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/translate.js:491:12)
            at cypherQuery (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/index.js:146:40)

EDIT:
Found out that @neo4j_ignore can be used instead, but this still shouldn't be necessary if a custom resolver was found.

Most helpful comment

@bwalsh
You are very welcome 馃槉
I'm glad it helps!

All 6 comments

I agree, it shouldn't be necessary and it would be quite helpful if @neo4j_ignore was added to the documentation.

@viktorstrate Are you happy to share your custom resolver?

I'm hoping it'll help me get to the bottom of #144.

@mmmoli, I came by the issue, when developing my side project Photoview.

I've created a new branch on the project, to make it easier to setup a proof of concept.

Steps to reproduce

  1. Clone the branch:
    $ git clone --branch issue478 https://github.com/viktorstrate/photoview.git

  2. Start a Neo4j server with username neo4j and password letmein,
    running on the default host (bolt://localhost:7687)

  3. Start the back-end server
    $ cd api
    $ npm install
    $ npm run start-dev
    The graphql playground should then be available at http://localhost:4001/graphql

  4. Make dummy photo, by running the following Cypher query:
    CREATE (p:Photo { title: 'Test Photo' })

  5. Run the following Graphql query, in the playground

query {
  Photo {
    title
    thumbnail {
      path
    }
} }

And you should get the following result:

{
  "data": {
    "Photo": [
      {
        "title": "Test Photo",
        "thumbnail": {
          "path": "http://localhost:4001/images/undefined/thumbnail.jpg"
        }
} ] } }
  1. Now change the schema located at api/src/schema.graphql.
    Find the Photo type and remove @neo4j_ignore

  2. Rerun the Graphql query in the playground from step 5,
    you should now get the "Cannot read property '0' of undefined" error.
    You might have to restart the server, before the schema is updated.

@viktorstrate
Thanks very much for an excellent explanation and example project to illustrate the problem.
Saved me a bunch of time. Nice Work!

@bwalsh
You are very welcome 馃槉
I'm glad it helps!

Another hack/workaround is to annotate the field with a redundant @cypher directive. Either way, I prefer the text inside the @relation or @cypher statement to say something like DEFINED_IN_RESOLVER! so at least if someone else encounters the code at a glance they know what's up.

@johnymontana Any ideas of how to solve this? Because I've also encountered this when defining custom field resolvers and it's pretty jolly poor. Anyone who has to derive a complicated computed field (something that doesn't directly live in the database or can't be computed within a cypher statement) is going to run into this. It should just work out of the box, the library shouldn't break the resolver pattern.

If it's too difficult to work transparently, then perhaps we could have a custom directive like @use_resolver as an alternative. Because one may well want to _expose_ that field and as such using @neo4j_ignore is a non-option.

Was this page helpful?
0 / 5 - 0 ratings