5

I am following schema same as mentioned here

I want to fetch all users so I updated my schema like this

var Root = new GraphQLObjectType({
  name: 'Root',
  fields: () => ({
    user: {
      type: userType,
      resolve: (rootValue, _) => {
        return getUser(rootValue)
      }
    },
    post: {
      type: postType,
      args: {
         ...connectionArgs,
          postID: {type: GraphQLString}
        },
      resolve: (rootValue, args) => {
       return getPost(args.postID).then(function(data){
        return data[0];
       }).then(null,function(err){
        return err;
       });
      }
    },

    users:{
      type: new GraphQLList(userType),
      resolve: (root) =>getUsers(),
    },
  })
});

And in database.js

export function getUsers(params) {
  console.log("getUsers",params)
  return new Promise((resolve, reject) => {
      User.find({}).exec({}, function(err, users) {
        if (err) {
          resolve({})
        } else {
          resolve(users)
        }
      });
  })
}

I am getting results in /graphql as

{
  users {
    id,
    fullName
  } 
}

and results as

{
  "data": {
    "users": [
      {
        "id": "VXNlcjo1Nzk4NWQxNmIwYWYxYWY2MTc3MGJlNTA=",
        "fullName": "Akshay"
      },
      {
        "id": "VXNlcjo1Nzk4YTRkNTBjMWJlZTg1MzFmN2IzMzI=",
        "fullName": "jitendra"
      },
      {
        "id": "VXNlcjo1NzliNjcyMmRlNjRlZTI2MTFkMWEyMTk=",
        "fullName": "akshay1"
      },
      {
        "id": "VXNlcjo1NzliNjgwMDc4YTYwMTZjMTM0ZmMxZWM=",
        "fullName": "Akshay2"
      },
      {
        "id": "VXNlcjo1NzlmMTNkYjMzNTNkODQ0MmJjOWQzZDU=",
        "fullName": "test"
      }
    ]
  }
}

but If I try to fetch this in view as

export default Relay.createContainer(UserList, {
  fragments: {
    userslist: () => Relay.QL`
      fragment on User @relay(plural: true) {
            fullName,
            local{
              email
            },
            images{
              full
            },
            currentPostCount,
            isPremium,
      }
    `,
  },
});

I am getting error Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.

Please tell me what I am missing . I tried a lot with and without @relay(plural: true). Also tried to update schema with arguments as

    users:{
      type: new GraphQLList(userType),
      args: {
        names: {
          type: GraphQLString,
        },
        ...connectionArgs,
      },
      resolve: (root, {names}) =>connectionFromArray(getUsers(names)),
    },

but I got error Cannot read property 'after' of undefined in implementing react-relay Thanks in Advance.

Community
  • 1
  • 1
akshay
  • 1,151
  • 1
  • 19
  • 31
  • Where do you define `userslist`? – Ahmad Ferdous Aug 04 '16 at 17:04
  • I defined user list in routes.js – akshay Aug 04 '16 at 17:12
  • Relay.ql'{ users} – akshay Aug 04 '16 at 17:13
  • 1
    As the error suggested, did you try out non minified dev environment and get a detailed error message? – Ahmad Ferdous Aug 04 '16 at 18:55
  • I got message Invariant Violation: RelayOSSNodeInterface: Expected payload for root field `users` to be a single non-array result, instead received an array with 5 results – akshay Aug 05 '16 at 06:13
  • Which version of Relay are you using? List-type root field in query is now supported. – Ahmad Ferdous Aug 05 '16 at 12:01
  • here are versions list of all relays packages , "react-relay": "0.8.1", "graphql-relay": "0.4.1", "isomorphic-relay-router": "0.8.0-beta.0", "isomorphic-relay": "0.7.0-beta.0", "relay-local-schema": "0.5.0", "babel-relay-plugin": "0.8.1", – akshay Aug 05 '16 at 12:15
  • It may be a good idea to look at star-wars example of relay. It also has a query where a [root query field is a list](https://github.com/relayjs/relay-examples/blob/3a134b03fa9b741754f0b2e6ad15b5da79151846/star-wars/data/schema.js#L234). – Ahmad Ferdous Aug 05 '16 at 19:38

1 Answers1

8

Relay currently only supports three types of root fields (see facebook/relay#112):

  • Root field without arguments, returning a single node:
    • e.g. { user { id } } returning {"id": "123"}
  • Root field with one argument, returning a single node:
    • e.g. { post(id: "456") { id } } returning {"id": "456"}
  • Root field with one array argument returning an array of nodes with the same size as the argument array (also known as "a plural identifying root field"):
    • e.g. { users(ids: ["123", "321"]) { id } } returning [{"id": "123"}, {"id": "321"}]

A workaround is to create a root field (often called viewer) returning a node that has those fields. When nested inside the Viewer (or any other node), fields are allowed to have any return type, including a list or connection. When you've wrapped the fields in this object in your GraphQL server, you can query them like this:

{
  viewer {
    users {
      id,
      fullName,
    }
  }
}

The Viewer type is a node type, and since there will just be one instance of it, its id should be a constant. You can use the globalIdField helper to define the id field, and add any other fields you want to query with Relay:

const viewerType = new GraphQLObjectType({
  name: 'Viewer',
  interfaces: [nodeInterface],
  fields: {
    id: globalIdField('Viewer', () => 'VIEWER_ID'),
    users:{
      type: new GraphQLList(userType),
      resolve: (viewer) => getUsers(),
    },
  },
});

On the client you'll need to change the root query in your route to { viewer } and define the fragment on Viewer:

export default Relay.createContainer(UserList, {
  fragments: {
    viewer: () => Relay.QL`
      fragment on Viewer {
        users {
          fullName,
          local {
            email,
          },
          images {
            full,
          },
          currentPostCount,
          isPremium,
        }
      }
    `,
  },
});
fson
  • 860
  • 8
  • 9