-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nested fields issue #154
Comments
edges: above points directly to a type rather than to a field definition object which includes "type" and "description" properties. I'll try to make this a fast fail error so it's easier to catch |
@leebyron Yeah, I've forgot to specify it here. I've found the problem. Can you tell me how can I operate with virtual fields in my schema? In this example I do not have |
I've done now with following example. Please do not think of edges in terms of Relay. In my code I'd want to store all the relations under the const userEdge = new GraphQLObjectType({
name: 'UserEdge',
fields: () => ({
todos: {
type: new GraphQLList(todoType),
description: 'User todos',
args: {
count: {
name: 'count',
type: GraphQLInt,
},
},
resolve: (user, params, { rootValue }) => {
return findTodo(params);
},
},
}),
});
const userType = new GraphQLObjectType({
name: 'User',
description: 'User type',
fields: () => ({
id: {
type: new GraphQLNonNull(GraphQLString),
description: 'User id',
},
name: {
type: new GraphQLNonNull(GraphQLString),
description: 'User name',
},
edges: {
type: new GraphQLList(userEdge),
resolve: (user, args, info) => {
// Here I'd like to delegate execution to the edge fields
},
},
}),
}); My query:
Expected result: "viewer": {
"id": 'u-1',
"name": "user",
"edges": {
"todos": [/* array of todos*/]
}
} What should I write in the |
Just pass what you need in todos as a result of resolve of edges. If you have overridden all children resolves you can use the result of resolve to pass info. |
@freiksenet like this? const userType = new GraphQLObjectType({
name: 'User',
description: 'User type',
fields: () => ({
id: {
type: new GraphQLNonNull(GraphQLString),
description: 'User id',
},
name: {
type: new GraphQLNonNull(GraphQLString),
description: 'User name',
},
edges: {
type: new GraphQLList(userEdge),
resolve: (...args) => {
return { todos: edgeType.fields().todos(...args) }
},
},
}),
}); |
This is one way, then you actually don't need a You should also move count to edges arguments, not the Edge type. |
You basically can do this stuff in two ways.
|
Thanks to @freiksenet for helping in solving this issue. If anyone cares about the solution it is a follows: const userEdges = new GraphQLObjectType({
name: 'UserEdges',
fields: () => ({
todos: {
type: new GraphQLList(todoType),
description: 'User todos',
args: {
count: {
name: 'count',
type: GraphQLInt,
},
},
resolve: (user, params, { rootValue }) => {
return findTodo(params);
},
},
}),
});
const userType = new GraphQLObjectType({
name: 'User',
description: 'User type',
fields: () => ({
id: {
type: new GraphQLNonNull(GraphQLString),
description: 'User id',
},
name: {
type: new GraphQLNonNull(GraphQLString),
description: 'User name',
},
edges: {
type: userEdges,
resolve: () => ({})
},
}),
}); @leebyron This case is about adding virtual field into the schema. I think that GraphQL can provide quite better API for it. The idea here is if we provide plain JS object as a field simply delegate execution to its children. const userType = new GraphQLObjectType({
name: 'User',
description: 'User type',
fields: () => ({
id: {
type: new GraphQLNonNull(GraphQLString),
description: 'User id',
},
name: {
type: new GraphQLNonNull(GraphQLString),
description: 'User name',
},
edges: {
todos: {
type: new GraphQLList(todoType),
description: 'User todos',
args: {
count: {
name: 'count',
type: GraphQLInt,
},
},
resolve: (user, params, { rootValue }) => {
return findTodo(params);
},
},
},
}),
}); |
I'm sorry but I don't follow any of this. I'm probably tainted by my understanding of what You have Edges defined as a list of
I'm sorry, I don't follow this at all. What does "virtual field" refer to in your parlance? Is If I reframe your example as:
could you explain what you expect |
@leebyron Sorry for confusing name. I do not use From your comment I suppose that you rely on the code in the beginning of that issue. But its not reliable anymore. Please check code in the first half of this comment. Here there is no |
What is unclear to me is the role of for example, this works fine, as pointed above in this thread const { graphql, GraphQLObjectType, GraphQLNonNull, GraphQLInt, GraphQLString, GraphQLList, GraphQLSchema } = require('graphql');
const getStuffs = () => Array.from({ length: 50 }, (_, i) => ({ id: `_${i}`, name: `n${i}` }));
const StuffType = new GraphQLObjectType({
name: 'Stuff',
description: 'Some stuff',
fields: () => ({
id: {
type: new GraphQLNonNull(GraphQLString),
description: 'Stuff id',
},
name: {
type: GraphQLString,
description: 'Stuff name',
},
custom: {
type: GraphQLString,
description: 'cus',
resolve: () => 'ok',
}
})
});
const QueryType = new GraphQLObjectType({
name: 'Query',
description: 'The root of all... queries',
fields: () => ({
stuffs: {
type: new GraphQLList(StuffType),
description: '..',
args: {
first: {
name: 'first',
type: GraphQLInt,
},
},
resolve: (o, { first = 20 } = {}) => getStuffs().slice(0, first)
}
})
});
const schema = new GraphQLSchema({
query: QueryType,
});
const gql = (source, variableValues) => graphql({
schema,
source,
variableValues,
});
(async () => {
const d = await gql(`{
stuffs(first: 10){
id
name
custom
}
}`);
console.log(d.data.stuffs); // returns arrays of `{ id: '_4', name: 'n4', custom: 'ok' }` ,'s
})(); but using const { graphql, buildSchema } = require('graphql');
const str = `
type Query {
rand: [Float]
stuffs(first: Int): [Stuff]
}
type Stuff {
id: ID!
name: String
custom: String
}
`;
const schema = buildSchema(str);
const getStuffs = () => Array.from({ length: 50 }, (_, i) => ({ id: `_${i}`, name: `n${i}` }));
const rootValue = {
stuffs: ({ first = 20 }) => getStuffs().slice(0, first),
Stuff: {
custom: () => 'ok',
}
};
const gql = (source, variableValues) => graphql({
schema,
rootValue,
source,
variableValues,
});
(async () => {
const d = await gql(`{
stuffs(first: 10){
id
name
custom
}
}`);
console.log(d.data.stuffs); // returns arrays of `{ id: '_4', name: 'n4', custom: null }` ,'s
})(); the computed field It'd be possible to manually merge that computed field in the root query adding a It's what Basically I would prefer the second approach for defining schemas, but still allow computed fields. Or understand why they are not equivalent (note: I intentionally omitted |
@caub It's better to use stack overflow for such questions: https://github.com/graphql/graphql-js/blob/master/.github/ISSUE_TEMPLATE.md#questions-regarding-how-to-use-graphql
It uses a different approach to the problem.
You return new root value from const { graphql, buildSchema } = require('graphql');
const str = `
type Query {
rand: [Float]
stuffs(first: Int): [Stuff]
}
type Stuff {
id: ID!
name: String
custom: String
}
`;
const schema = buildSchema(str);
class Stuff {
constructor(i) {
this.id = `_${i}`;
this.name = `n{i}`;
}
custom() {
return 'ok';
}
}
const getStuffs = () => Array.from({ length: 50 }, (_, i) => new Stuff(i));
const rootValue = {
rand: () => Array.from({ length: 10 }, () => Math.random()),
stuffs: ({ first = 20 }) => getStuffs().slice(0, first),
};
const gql = (source, variableValues) => graphql({
schema,
rootValue,
source,
variableValues,
});
(async () => {
const d = await gql(`{
stuffs(first: 10){
id
name
custom
}
}`);
console.log(d.data.stuffs); // returns arrays of `{ id: '_4', name: 'n4', custom: 'ok' }` ,'s
})(); |
Consider following code:
Schema:
Query:
In the query result
edges
field isnull
. Is it a bug or I do something wrong?The text was updated successfully, but these errors were encountered: