I am trying to return a graphQL query with some nested property objects in a list. Everything seems to check out, but am getting null values.
Expected datastructure response (more detail on structure here):
//Return a GraphQLList type of all objects :
[
{
"subscription" : {
},
"customer" : {
},
},
]
the query: { subscriptions { subscription { id customer_id } } }
GraphQL Query Object:
var Query = new graphQL.GraphQLObjectType({
name: 'Query',
description: 'Root of the Schema',
fields: {
subscriptions: {
type: new graphQL.GraphQLList(SubscriptionsList),
args : {
customer_name: { type: graphQL.GraphQLString },
customer_id: { type: graphQL.GraphQLString }
},
resolve : function (source, args) {
return getSubscriptions().then(function (res) {
// Shows that data is returned
console.log('Data: ', res.list);
return res.list;
}).catch(function (err) {
return err;
});
}
}
}
});
Which expects to return type GraphQLList
of SubscriptionsList
:
var SubscriptionsList = new graphQL.GraphQLObjectType({
name : 'SubscriptionObj',
description : 'stuff',
fields : function () {
return {
subscription : {
type : Subscription,
resolve : function (subscription) {
return subscription;
}
}
}
}
});
Which should resolve the nested field property:
var Subscription = new graphQL.GraphQLObjectType({
name : 'Subscription',
description : 'stuff',
fields : function () {
return {
id: {type: graphQL.GraphQLString},
customer_id: {type: graphQL.GraphQLString}
}
}
});
Console.log(res.list) Output (from Query): I am definitely getting the data and structure I expect:
[ { subscription:
{ id: 'cbdemo_lloyd-sub2',
customer_id: 'cbdemo_lloyd',
plan_id: 'cbdemo_nuts',
addons: [Object],
due_invoices_count: 0,
shipping_address: [Object] },
customer: {
...
}
},
{...}
]
GraphQL Query Output:
{
"data": {
"subscriptions": [
{
"subscription": {
"id": null,
"customer_id": null
}
},
{
"subscription": {
"id": null,
"customer_id": null
}
},
EDIT Not really necessary, but here is the getSubscriptions()
API call that returns a promise:
function getSubscriptions() {
return new Promise(function (resolve, reject) {
chargebee.subscription.list({
limit : 5,
"plan_id[is_not]" : "basic",
"status[is]" : "active",
"sort_by[asc]" : "created_at"
}).request(function(error,result){
if (error) return reject(error);
return resolve(result);
});
});
}
I am trying to return a graphQL query with some nested property objects in a list. Everything seems to check out, but am getting null values.
Expected datastructure response (more detail on structure here):
//Return a GraphQLList type of all objects :
[
{
"subscription" : {
},
"customer" : {
},
},
]
the query: { subscriptions { subscription { id customer_id } } }
GraphQL Query Object:
var Query = new graphQL.GraphQLObjectType({
name: 'Query',
description: 'Root of the Schema',
fields: {
subscriptions: {
type: new graphQL.GraphQLList(SubscriptionsList),
args : {
customer_name: { type: graphQL.GraphQLString },
customer_id: { type: graphQL.GraphQLString }
},
resolve : function (source, args) {
return getSubscriptions().then(function (res) {
// Shows that data is returned
console.log('Data: ', res.list);
return res.list;
}).catch(function (err) {
return err;
});
}
}
}
});
Which expects to return type GraphQLList
of SubscriptionsList
:
var SubscriptionsList = new graphQL.GraphQLObjectType({
name : 'SubscriptionObj',
description : 'stuff',
fields : function () {
return {
subscription : {
type : Subscription,
resolve : function (subscription) {
return subscription;
}
}
}
}
});
Which should resolve the nested field property:
var Subscription = new graphQL.GraphQLObjectType({
name : 'Subscription',
description : 'stuff',
fields : function () {
return {
id: {type: graphQL.GraphQLString},
customer_id: {type: graphQL.GraphQLString}
}
}
});
Console.log(res.list) Output (from Query): I am definitely getting the data and structure I expect:
[ { subscription:
{ id: 'cbdemo_lloyd-sub2',
customer_id: 'cbdemo_lloyd',
plan_id: 'cbdemo_nuts',
addons: [Object],
due_invoices_count: 0,
shipping_address: [Object] },
customer: {
...
}
},
{...}
]
GraphQL Query Output:
{
"data": {
"subscriptions": [
{
"subscription": {
"id": null,
"customer_id": null
}
},
{
"subscription": {
"id": null,
"customer_id": null
}
},
EDIT Not really necessary, but here is the getSubscriptions()
API call that returns a promise:
function getSubscriptions() {
return new Promise(function (resolve, reject) {
chargebee.subscription.list({
limit : 5,
"plan_id[is_not]" : "basic",
"status[is]" : "active",
"sort_by[asc]" : "created_at"
}).request(function(error,result){
if (error) return reject(error);
return resolve(result);
});
});
}
Share
Improve this question
asked Aug 30, 2016 at 22:20
user3871user3871
12.7k36 gold badges140 silver badges282 bronze badges
3 Answers
Reset to default 3Looks like you are getting abit confused, Basiclly, when you set
new graphQL.GraphQLList(SubscriptionsList),
this is already a list. which means what you really meant is
new graphQL.GraphQLList(Subscription),
Next, your subscription object does not contain any resolve logic, so i would expect it to be something like this:
var Subscription = new graphQL.GraphQLObjectType({
name : 'Subscription',
description : 'stuff',
fields : function () {
return {
id: {
type: graphQL.GraphQLString,
resolve: function(subscription) {
return subscription.subscription.id;
}
},
customer_id: {
type: graphQL.GraphQLString,
resolve: function(subscription) {
return subscription.subscription.customer_id;
}
},
}
}
});
What basically happens under the hood, is that GraphQL will resolve each javascript object in the list provided, using the Subscription object. each resolver there will get the javascript object as the first value, and return the basic value from it.
I think the resolver in your SubscriptionsList has to return subscription.subscription
. I would consider changing the name of subscriptionsList, because it's quite confusing.
The way I see it, you should just have a GraphQLList(Subscription) and remove that extra level of nesting. Either that, or call the thing that contains a subscription and a customer something else.
According to your post, res.list
shows the following:
// listing #1
[
{
subscription: {
id: 'cbdemo_lloyd-sub2',
customer_id: 'cbdemo_lloyd',
plan_id: 'cbdemo_nuts',
addons: [Object],
due_invoices_count: 0,
shipping_address: [Object] },
customer: {
...
}
},
{...}
]
Now, the above result corresponds to subscriptions
field in your Query
, which is a list of SubscriptionsList
. Therefore, value of a SubscriptionsList
will be item from the above listing #1:
// listing #2
{
subscription: {
id: 'cbdemo_lloyd-sub2',
customer_id: 'cbdemo_lloyd',
plan_id: 'cbdemo_nuts',
addons: [Object],
due_invoices_count: 0,
shipping_address: [Object] },
customer: {
...
}
}
}
In SubscriptionsList
type, you have a field subscription
. Its resolve function returns whatever it gets. So the field subscription
remains the same as listing #2.
While resolving subscription
field (type Subscription
), it looks for id
and customer_id
properties in object shown in listing #2. But that object has only subscription
property. Therefore, id
and customer_id
fields receive null
values.
Thus, the problem is in the resolve function of subscription
field. Its input is object in listing #2 and its output should be the object in the following listing #3:
// listing #3
{
id: 'cbdemo_lloyd-sub2',
customer_id: 'cbdemo_lloyd',
plan_id: 'cbdemo_nuts',
addons: [Object],
due_invoices_count: 0,
shipping_address: [Object] },
customer: {
...
}
}
To get the object in listing #3, change in your SubscriptionsList
type:
subscription : {
type : Subscription,
resolve : function (item) { // item is listing #2
return item.subscription; // item.subscription is listing #3
}
}
On a different note, the GraphQL object type SubscriptionsList
is actually unnecessary here and made the whole thing plicated. The whole design will bee a lot simpler without it.