Reputation: 927
I'm stuck on an error on my GraphQL
and Sequelize
backend, for some reason my mutation doesn't return the data, even though I guarantee there's data being returned inside my resolver. I feel like this is probably something small that I'm missing, but I've been stuck for awhile.
The Sequelize
part works, the object is indeed inserted, however the return is always a null object.
Here's my mutation:
mutation {
createUserVoucher(pinId: 1, voucherId: 1) {
id
}
}
Here's the return:
{
"data": {
"createUserVoucher": {
"id": null
}
}
}
Here's my resolver:
createUserVoucher: (parent, args, { user, models }) => {
args['userId'] = user.id;
models.UserVoucher.count({
where: {utilized: true, pinId: args.pinId, userId: args.userId}
}).then( c => {
if (c > 0) {
return []
} else {
models.Voucher.findOne({
where: {
id: args.voucherId
}
}).then( voucher => {
models.UserVoucher.count({
where: { voucherId: args.voucherId }
}).then( c => {
return models.UserVoucher.create(args)
})
})
}
});
return []
}
UserVoucher definition:
type UserVoucher {
id: Int
nodeId: Int!
userId: ID!
voucherId: ID!
voucher: Voucher
pinId: ID!
capturedAt: DateTime
utilized: Boolean
}
`;
Mutation definition:
createUserVoucher(
pinId: Int!,
voucherId: Int!
): UserVoucher
Any ideas on what I'm missing? It will be much appreciated, thank you very much!! Also if any more information is needed, let me know!
Upvotes: 0
Views: 245
Reputation: 84687
You're missing three returns:
createUserVoucher: (parent, args, { user, models }) => {
args['userId'] = user.id;
return models.UserVoucher.count({ <----- HERE
where: {utilized: true, pinId: args.pinId, userId: args.userId}
}).then( c => {
if (c > 0) {
return []
} else {
return models.Voucher.findOne({ // <----- HERE
where: {
id: args.voucherId
}
}).then( voucher => {
return models.UserVoucher.count({ // <----- AND HERE
where: { voucherId: args.voucherId }
}).then( c => {
return models.UserVoucher.create(args)
})
})
}
});
return []
}
When chaining promises, it's important to remember to always return any additional promises inside each then
call -- otherwise the promise is fired but it's not awaited.
Couple of additional notes:
While strictly not hurting anything, you should return null
instead of an empty array inside your resolver. According to your schema, your mutation returns a nullable UserVoucher object. Returning an empty array is misleading to anyone reading your code because it implies this resolver should be returning a array.
The results from the second UserVoucher.count
call and the Voucher.findOne
call aren't used, which means they might not be necessary?
Lastly, you can also significantly clean up your code by using async/await:
createUserVoucher: async (parent, args, { user, models }) => {
args['userId'] = user.id;
const c = await models.UserVoucher.count({
where: {utilized: true, pinId: args.pinId, userId: args.userId}
})
if (c > 0) return null
const voucher = await models.Voucher.findOne({
where: { id: args.voucherId }
})
const c2 = await models.UserVoucher.count({
where: { voucherId: args.voucherId }
})
return models.UserVoucher.create(args) // still need a return here
}
Upvotes: 1