Skip to content
This repository has been archived by the owner on Sep 3, 2021. It is now read-only.

TypeError: Cannot read property 'selections' of undefined #145

Closed
Banhawy opened this issue Nov 22, 2018 · 9 comments
Closed

TypeError: Cannot read property 'selections' of undefined #145

Banhawy opened this issue Nov 22, 2018 · 9 comments

Comments

@Banhawy
Copy link

Banhawy commented Nov 22, 2018

I have the following GraphQL schema:

type User {
    fName: String!
    lName: String!
    socialAccounts: SocialMedia @relation(name: "HAS", direction: "OUT")
}

input UserInput {
    fName: String!
    lName: String!
    SocialMedia: SocialMediaInput
}

type SocialMedia {
    facebook: Facebook
}

input SocialMediaInput {
    facebook: FacebookInput
}

type Facebook {
    url: String
}

input FacebookInput {
    url: String
}

type Mutation {
    UpdateSocialMedia(user: UserInput): String @cypher(
        statement: "MERGE (u:User) WHERE u.lName = $user.lName MERGE (m:Facebook) WHERE m.url = $user.SocialMedia.facebook.url MERGE (u)-[:HAS]->(m) return m"
    )
}

I am trying to create a mutation that can update a user's social media url where that social media type is a labeled node in neo4j. The problem I get is that the GraphQL mutation doesn't execute. The following mutation:

UpdateSocialMedia(
    user: {
      fName: "Adham",
      lName: "El Banhawy",
      SocialMedia: {
        facebook: {
          url: "https://www.facebook.com/benhawy"
        }
      }
    }
  )

gives me the following error stack:

"errors": [
    {
      "message": "Cannot read property 'selections' of undefined",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "UpdateSocialMedia"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "stacktrace": [
            "TypeError: Cannot read property 'selections' of undefined",
            "    at cypherMutation (A:\\Coding\\projects\\ProjectX\\api\\node_modules\\neo4j-graphql-js\\dist\\index.js:244:84)",
            "    at _callee$ (A:\\Coding\\projects\\ProjectX\\api\\node_modules\\neo4j-graphql-js\\dist\\index.js:65:31)",
            "    at tryCatch (A:\\Coding\\projects\\ProjectX\\api\\node_modules\\babel-runtime\\node_modules\\regenerator-runtime\\runtime.js:62:40)",
            "    at Generator.invoke [as _invoke] (A:\\Coding\\projects\\ProjectX\\api\\node_modules\\babel-runtime\\node_modules\\regenerator-runtime\\runtime.js:296:22)",
            "    at Generator.prototype.(anonymous function) [as next] (A:\\Coding\\projects\\ProjectX\\api\\node_modules\\babel-runtime\\node_modules\\regenerator-runtime\\runtime.js:114:21)",
            "    at step (A:\\Coding\\projects\\ProjectX\\api\\node_modules\\babel-runtime\\helpers\\asyncToGenerator.js:17:30)",
            "    at A:\\Coding\\projects\\ProjectX\\api\\node_modules\\babel-runtime\\helpers\\asyncToGenerator.js:35:14",
            "    at Promise (<anonymous>)",
            "    at F (A:\\Coding\\projects\\ProjectX\\api\\node_modules\\core-js\\library\\modules\\_export.js:36:28)",
            "    at A:\\Coding\\projects\\ProjectX\\api\\node_modules\\babel-runtime\\helpers\\asyncToGenerator.js:14:12"
          ]
        }
      }
    }
  ],

Is there a way to get this working to match the GraphQL mutation format?

Neo4j Version: 3.4.1 Enterprise
neo4j-graphql Version: 3.4.0.1

@ziiko10
Copy link

ziiko10 commented Nov 22, 2018

Hello , can you give us the code of your back end api ? in where you consume the mutation please ?

@Banhawy
Copy link
Author

Banhawy commented Nov 22, 2018

Sure.

My index.js:

import { typeDefs, resolvers } from "./graphql-schema";
import { ApolloServer, gql, makeExecutableSchema } from "apollo-server";
import { v1 as neo4j } from "neo4j-driver";
import fs from 'fs';
import { augmentSchema } from "neo4j-graphql-js";
import dotenv from "dotenv";

dotenv.config();

const schema = makeExecutableSchema({
    typeDefs,
    resolvers
});

/**
 * A cobfiguration object to exert more control on the schema augmentation process
 * and the aut0-generation of mutations and queries
 */
const config = {
    query: {
        exclude: ["User"]
    },
    mutation: false
}

const augmentedSchema = augmentSchema(schema, config);

const driver = neo4j.driver(
    process.env.NEO4J_URI || "bolt://localhost:7687",
    neo4j.auth.basic(
        process.env.NEO4J_USER || "neo4j",
        process.env.NEO4J_PASSWORD || "neo4j"
    )
);

const server = new ApolloServer({
    context: { driver },
    // remove schema and uncomment typeDefs and resolvers above to use original (unaugmented) schema
    schema: augmentedSchema,
    tracing: true
});

server.listen(process.env.GRAPHQL_LISTEN_PORT, '0.0.0.0').then(({ url }) => {
    console.log(`GraphQL API ready at ${url}`);
}).catch((e) => {
    console.log("error:", e);
});

My graphql-schema.js:

import { neo4jgraphql } from "neo4j-graphql-js";
import { gql } from "apollo-server";
import path from 'path';

let schema = fs.readFileSync(process.env.GRAPHQL_SCHEMA || path.join(__dirname, "schema.graphql"))
    .toString('utf-8');

export const typeDefs = gql `
${schema}
`;

export const resolvers = {
    Mutation: {
        UpdateSocialMedia(object, params, ctx, resolveInfo) {
            return neo4jgraphql(object, params, ctx, resolveInfo, true)
        }
    }
};

At this point I am only testing the mutation in the GraphQL Playground/editor.

@ziiko10
Copy link

ziiko10 commented Nov 22, 2018

Can you send me screen shot of your GraphQL Playground/editor reponse ?

@Banhawy
Copy link
Author

Banhawy commented Nov 22, 2018

Here's the screenshot:
screenshot-localhost-4040-2018 11 22-20-40-48

@johnymontana
Copy link
Contributor

@Banhawy It seems we assume mutations will return object types, and not scalars. As a workaround can you try returning the User in your mutation:

type Mutation {
    UpdateSocialMedia(user: UserInput): User @cypher(
        statement: "MERGE (u:User {lName: $user.lName}) MERGE (m:Facebook {url: $user.SocialMedia.facebook.url}) MERGE (u)-[:HAS]->(m) return u"
    )
}

NOTE: I also changed your Cypher query a bit - WHERE can't be used with MERGE, instead use the inline curly braces.

@btroop
Copy link

btroop commented Feb 1, 2019

I seem to be running into a similar issue, but on the Query type:

type User {
  uuid: ID
  firstName: String
  lastName: String
}

type Query {
 userCount: Int @cypher(statement:"Match (:User) RETURN COUNT(*)")
}

resulting in the following playground response:

{
  "errors": [
    {
      "message": "Cannot read property 'selections' of undefined",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "userCount"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "stacktrace": [
            "TypeError: Cannot read property 'selections' of undefined",
            "    at getQuerySelections (/Users/ben/Application Development/ag-app-grand-stack/api/node_modules/neo4j-graphql-js/dist/utils.js:915:63)",
            "    at cypherQuery (/Users/ben/Application Development/ag-app-grand-stack/api/node_modules/neo4j-graphql-js/dist/index.js:116:50)",
            "    at _callee$ (/Users/ben/Application Development/ag-app-grand-stack/api/node_modules/neo4j-graphql-js/dist/index.js:45:31)",
            "    at tryCatch (/Users/ben/Application Development/ag-app-grand-stack/api/node_modules/regenerator-runtime/runtime.js:62:40)",
            "    at Generator.invoke [as _invoke] (/Users/ben/Application Development/ag-app-grand-stack/api/node_modules/regenerator-runtime/runtime.js:296:22)",
            "    at Generator.prototype.(anonymous function) [as next] (/Users/ben/Application Development/ag-app-grand-stack/api/node_modules/regenerator-runtime/runtime.js:114:21)",
            "    at step (/Users/ben/Application Development/ag-app-grand-stack/api/node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)",
            "    at /Users/ben/Application Development/ag-app-grand-stack/api/node_modules/babel-runtime/helpers/asyncToGenerator.js:35:14",
            "    at new Promise (<anonymous>)",
            "    at new F (/Users/ben/Application Development/ag-app-grand-stack/api/node_modules/core-js/library/modules/_export.js:36:28)"
          ]
        }
      }
    }
  ],
  "data": {
    "userCount": null
  }
}

I tried adjusting the query to return an array of the User types:

type Query {
  userCount: [User] @cypher(statement:"Match (u:User) RETURN u")
}

which creates the following playground error:

{
  "errors": [
    {
      "message": "Invalid input ',': expected whitespace, comment or an expression (line 1, column 60 (offset: 59))\n\"WITH apoc.cypher.runFirstColumn(\"Match (u:User) RETURN u\", , True) AS x UNWIND x AS `user`\"\n                                                            ^",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "userCount"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "code": "Neo.ClientError.Statement.SyntaxError",
          "name": "Neo4jError",
          "stacktrace": [
            "Neo4jError: Invalid input ',': expected whitespace, comment or an expression (line 1, column 60 (offset: 59))",
            "\"WITH apoc.cypher.runFirstColumn(\"Match (u:User) RETURN u\", , True) AS x UNWIND x AS `user`\"",
            "                                                            ^",
            "",
            "    at captureStacktrace (/Users/ben/Application Development/ag-app-grand-stack/api/node_modules/neo4j-driver/lib/v1/result.js:200:15)",
            "    at new Result (/Users/ben/Application Development/ag-app-grand-stack/api/node_modules/neo4j-driver/lib/v1/result.js:73:19)",
            "    at Session._run (/Users/ben/Application Development/ag-app-grand-stack/api/node_modules/neo4j-driver/lib/v1/session.js:173:14)",
            "    at Session.run (/Users/ben/Application Development/ag-app-grand-stack/api/node_modules/neo4j-driver/lib/v1/session.js:154:19)",
            "    at _callee$ (/Users/ben/Application Development/ag-app-grand-stack/api/node_modules/neo4j-graphql-js/dist/index.js:60:28)",
            "    at tryCatch (/Users/ben/Application Development/ag-app-grand-stack/api/node_modules/regenerator-runtime/runtime.js:62:40)",
            "    at Generator.invoke [as _invoke] (/Users/ben/Application Development/ag-app-grand-stack/api/node_modules/regenerator-runtime/runtime.js:296:22)",
            "    at Generator.prototype.(anonymous function) [as next] (/Users/ben/Application Development/ag-app-grand-stack/api/node_modules/regenerator-runtime/runtime.js:114:21)",
            "    at step (/Users/ben/Application Development/ag-app-grand-stack/api/node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)",
            "    at /Users/ben/Application Development/ag-app-grand-stack/api/node_modules/babel-runtime/helpers/asyncToGenerator.js:35:14"
          ]
        }
      }
    }
  ],
  "data": {
    "userCount": null
  }
}

I've tried testing these in Neo4j desktop (I have the graphql plugin installed) and the queries seem work fine from that perspective.

Re: the second error, I'm wondering if it is related to the WITH apoc.cypher.runFirstColumn() procedure returning 'user' as a string rather than user as a neo4j variable.

My environment is set up nearly identically as @Banhawy (src.js files) except that I'm running 3.5.

Thoughts/help appreciated.

@btroop
Copy link

btroop commented Feb 1, 2019

Did some more digging into the second error. Might be more related to https://github.com/neo4j-graphql/neo4j-graphql-js/issues/159.

The apoc statement doesn't include a blank object in the second parameter reference
\"WITH apoc.cypher.runFirstColumn(\"Match (u:User) RETURN u\", , True) AS x UNWIND x AS `user`\"

adding a blank {} as the second argument seems to fix the issue in Neo4j desktop.

@johnymontana
Copy link
Contributor

Another example of this issue: https://community.neo4j.com/t/neo4j-grapql-js-custom-cypher-query/5017

@johnymontana
Copy link
Contributor

Fixed in #200

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants