I am using react-apollo on meteor with mysql and sequelize, I am still a beginner in JS. Lets assume I have the following resolver function on my apollo-server:
export default resolvers = {
Query: {
posts(_, args){
return Post.findAndCountAll({ where: args });
},
numberOfPosts(){
return /// the number of selected posts
}
}
I would like to select some data from the database where some conditions are met and then count the amount of selected rows and return them in the field "numberOfPosts".
findAndCountAll()
returns an object, which contains the selected rows and the count. I would like to get my post()
to return only the selected rows, and my numberOfPosts() to return only the count of the selected posts. Right now, both is returned by posts().
My schema is:
type Post {
id: Int
date: Float
text: String
}
type NumberOfPosts{
total: Int
filtered: Int
}
type Query {
posts(
id: Ind,
offset: Int,
limit: Int,
filter: String): [Post]
numberOfPosts:[NumberOfPosts]
}
schema {
query: Query
}
The Goal is to receive data in the following format:
{
"data": {
"numberOfPosts": [
{
"total": 1000,
"filtered": 21
}
],
"posts": [
{
"id": 4,
"date": 5105626122,
"text": "jzybiwutudi"
},
...
]
}
}
My work so far: Try 1:
let selectedCount;
export default resolvers = {
Query: {
posts(_, args){
return Post.findAndCountAll({where: args}).then(
function (results) {
selectedCount = results.count;
return results.rows
});
},
numberOfPosts(){
return selectedCount
}
}}
So I am defining a helping variable outside of resolvers, and set it to the number of selected rows, then the count is returned in numberOfPosts()
, which works, but the problem with this is, return results.rows
causes an error, and I do not understand why.
another issue is, that selectedCount
is always the previous number of rows
Try 2
Another solution that seems to work is to Pass the arguments twice into the GraphQL query, like so:
{
numberOfPosts(filter: "example") {
total
filtered
}
posts(filter: "example") {
id
date
text
}
}
Then both resolver functions know the same arguments, so I can select and count the same posts. But this looks not right to me, since I have to pass the same args twice, they will also be transmitted twice...
You should think more about the design and what each of those queries should do. Those queries should not mutate the database or the global state.
The best thing you can do is to simply define a new type that includes
total
andfiltered
, like what you did asNumberOfPosts
in your first try, and also the list of posts.So, your schema would be like:
And you resolve
posts
like:Notice how I just put 1000 for the total number. You can not get the total number of rows with
findAndCountAll
. If you that, need you can run two different queries in parallel and usePromise.all
to wait for them to be resolved.The above code also could benefit from ES6's destructuring:
Now you can run:
and get: