How to return an array of objects in GraphQL, possibly using the same endpoint as the one that returns a single object?
A Car and a List of Cars are effectively two separate types. A field cannot resolve to a single Car object one time, and an array of Car object another.
Your query is returning null for the name
because you told it the cars
field would resolve to a single object, but it resolved to an array instead. As a result, it's looking for a property called name
on the array object and since one doesn't exist, it's returning null.
You can handle this in a couple of different ways. To keep things to one query, you can use filter
instead of find
and change the type of your query to a List.
cars: {
type: new GraphQLList(CarType), // note the change here
args: {
id: {
type: GraphQLString
},
},
resolve: (parent, args) => {
if (args.id) {
return cars.filter(car => car.id === args.id);
}
return cars;
}
}
Alternatively, you could split this into two separate queries:
cars: {
type: new GraphQLList(CarType),
resolve: (parent, args) => cars,
},
car: {
type: CarType,
args: {
id: {
// example of using GraphQLNonNull to make the id required
type: new GraphQLNonNull(GraphQLString)
},
},
resolve: (parent, args) => cars.find(car => car.id === args.id),
}
Check the docs for more examples and options.
Haris Ghauri
Updated on July 25, 2022Comments
-
Haris Ghauri almost 2 years
I am making a GraphQL API where I would be able to retrieve a car object by its id or retrieve all the cars when no parameter is provided.
Using the code below, I am successfully able to retrieve a single car object by supplying id as a parameter.
However, in the case where I would expect an array of objects i.e. when I supply no parameter at all, I get no result on GraphiQL.
schema.js
let cars = [ { name: "Honda", id: "1" }, { name: "Toyota", id: "2" }, { name: "BMW", id: "3" } ]; const CarType = new GraphQLObjectType({ name: "Car", fields: () => ({ id: { type: GraphQLString }, name: { type: GraphQLString } }) }); const RootQuery = new GraphQLObjectType({ name: "RootQueryType", fields: { cars: { type: CarType, args: { id: { type: GraphQLString } }, resolve(parent, args) { if (args.id) { console.log(cars.find(car => car.id == args.id)); return cars.find(car => car.id == args.id); } console.log(cars); //***Problem Here*** return cars; } } } });
Test queries and their respective results:
Query 1
{ cars(id:"1"){ name } }
Query 1 Response (Success)
{ "data": { "cars": { "name": "Honda" } } }
Query 2
{ cars{ name } }
Query 2 Response (Fail)
{ "data": { "cars": { "name": null } } }
Any help would be much appreciated.