2
votes

I'm having a problem with querying some fields in graphql/relay. I'm trying to query the "courseName" field on Courses in the schema below.

If I query the User with for example:

{ user(id:1){firstname,lastname}}

It works and returns the correct response.

Here is my schema:

import {
  GraphQLBoolean,
  GraphQLFloat,
  GraphQLID,
  GraphQLInt,
  GraphQLList,
  GraphQLNonNull,
  GraphQLObjectType,
  GraphQLSchema,
  GraphQLString,
} from 'graphql';

import {
  connectionArgs,
  connectionDefinitions,
  connectionFromArray,
  fromGlobalId,
  globalIdField,
  mutationWithClientMutationId,
  nodeDefinitions,
} from 'graphql-relay';

import {
  // Import methods that your schema can use to interact with your database
  User,
  Course,
  getUser,
  getCourses
} from './database';

/**
 * We get the node interface and field from the Relay library.
 *
 * The first method defines the way we resolve an ID to its object.
 * The second defines the way we resolve an object to its GraphQL type.
 */
var {nodeInterface, nodeField} = nodeDefinitions(
  (globalId) => {
    var {type, id} = fromGlobalId(globalId);
    if (type === 'User') {
      return getUser(id);
   } else if (type === 'Course') {
      return getCourses(id);
    } else {
      return null;
    }
  },
  (obj) => {
    if (obj instanceof User) {
      return userType;
   } else if (obj instanceof Course)  {
      return courseType;
    } else {
      return null;
    }
  }
);

/**
 * Define your own types here
 */

var userType = new GraphQLObjectType({
  name: 'User',
  description: 'A person who uses our app',
  fields: () => ({
    id: globalIdField('User'),
    firstname : {
      type : GraphQLString,
      description : 'User First Name'
    },
    lastname :{
      type : GraphQLString,
      description : 'User Last Name'
    },
    email : {
      type : GraphQLString,
      description : 'User email'
    },
    company : {
      type : GraphQLString,
      description : 'User company'
    },
    courses: {
      type: courseConnection,
      description: 'A user\'s collection of courses',
      // args: {
      //   userId: {
      //     type: GraphQLInt
      //   }
      // },
      // resolve: (user, args) => connectionFromArray(getCourses(args.userId), args),
      args: connectionArgs,
      resolve: (user, args) => connectionFromArray(
        getCourses(user.id),
        args
      )
    },
  }),
  interfaces: [nodeInterface],
});

var courseType = new GraphQLObjectType({
  name: 'Course',
  description: 'A shiny course',
  fields: () => ({
    id: globalIdField('Course'),
    courseName: {
      type: GraphQLString,
      description: 'The name of the Course',
    }
  }),
  interfaces: [nodeInterface],
});

/**
 * Define your own connection types here
 */
var {connectionType: courseConnection} =
  connectionDefinitions({name: 'Course', nodeType: courseType});

/**
 * This is the type that will be the root of our query,
 * and the entry point into our schema.
 */
var queryType = new GraphQLObjectType({
  name: 'Query',
  fields: () => ({
    node: nodeField,
    // Add your own root fields here
    user: {
      type: userType,
      args: {
          id: { type: GraphQLInt }
      },
      resolve: (_,{id}) => getUser(id)
    }
  })
});

/**
 * This is the type that will be the root of our mutations,
 * and the entry point into performing writes in our schema.
 */
var mutationType = new GraphQLObjectType({
  name: 'Mutation',
  fields: () => ({
    // Add your own mutations here
  })
});

/**
 * Finally, we construct our schema (whose starting query type is the query
 * type we defined above) and export it.
 */
export var Schema = new GraphQLSchema({
  query: queryType,
  // Uncomment the following after adding some mutation fields:
  // mutation: mutationType
});

here is my database.js:

import Course from './models/course';
import User from './models/user';

module.exports = {

   User : User,
  // Export methods that your schema can use to interact with your database
  getUser: (id) => {
     return User.findOne( {_id: id}).exec();
  },
  getCourses: (userId) => {
     return Course.find( { userId : userId }).exec();
  },
  Course : Course
  // getCourse: (id) => widgets.find(w => w.id === id),
  // User,
  // Widget,
};

When I try to query for:

{ user (id:1){courses{courseName}} }

It gives me the error:

"Cannot query field 'courseName' in 'CourseConnection'"

It seems that it is a problem with the connection. Also I'm testing this queries with cURL. Since I want to test the schema before moving to react/relay.

What am I missing? Thank you.

1

1 Answers

6
votes

So, I found out why this was not working. I had to do the query in RelayJS style:

so:

{ user(id:1){courses(first:2){edges{node{courseName}}}} }