Strapi GraphQL query: "start" argument wouldn't work - strapi

I am running into a very strange problem with my queries in Strapi (version 3.0.0-alpha.26.2). I have a users collection with 3 documents that I'm trying to fetch via GraphQL. To fetch all users the query is:
users {
firstName
}
This returns the following:
{
"data": {
"users": [
{
"firstName": "Arnold"
},
{
"firstName": "Bill"
},
{
"firstName": "Vin"
}
]
}
}
3 names. Now, say, I wished to retrieve only the first 2 users. For such pagination use-cases, there's two arguments one could pass in a Strapi query: start (defines the index to start at) and limit (defines the number of elements to return). So now the query would be:
users(start: 0, limit: 2) {
firstName
}
This returns the first two names as expected:
{
"data": {
"users": [
{
"firstName": "Arnold"
},
{
"firstName": "Bill"
}
]
}
}
But what if I want the last 2 users here, i.e. Bill and Vin? Should be as straightforward as:
users(start: 1, limit: 2){
firstName
}
But this still returns Arnold and Bill, while you'd expect the following:
{
"data": {
"users": [
{
"firstName": "Bill"
},
{
"firstName": "Vin"
}
]
}
}
No matter what value I use for start, it always starts at the 0th item. You could do start: 200 (when there are only 3 items in the users collection) and it'd still return the exact same result! What sorcery is this??
The issue can be reproduced at https://dev.schandillia.com/graphql.

Related

What is proper way to use graphql query variables to search for values matching two different searches?

I have a "users" table that is connected to "interestTags" table. I would like to be able to search users interestTags and return all users that match one or more tags, In this example I would like to be able to return all users that has interestTags of either "dog" or "apple.
The code below is only showing matches for "apple" and leaving out the "dog" interestTag users. I would like to get both "dog" users and "apple" users returned instead of one or the other. How would I go about doing this? Here is my code:
users(offset: $offset, limit: 30, order_by: {lastRequest: asc}, where: {dob: {_gte: $fromDate, _lte: $toDate}, interestTagsFromSenderId: {_or: [{tag: $tagList}]}}) {
id
displayName
profilePhotoUrl
dob
bio
location
interestTags: interestTagsFromSenderId {
tag
}
created_at
}
}
graphql query variables:
{
"offset": 0,
"fromDate": "1999-07-01",
"toDate": "2024-01-01",
"tagList":
{
"_eq": "dog", "_eq": "apple"
}
}
This is what graphql is returning:
{
"data": {
"users": [
{
"id": 31,
"displayName": "n00b account",
"profilePhotoUrl": "default.jpg",
"dob": "2021-07-15",
"bio": null,
"location": null,
"interestTags": [
{
"tag": "apple"
}
],
"created_at": "2021-07-15T06:57:23.068243+00:00"
}
]
}
}
to fix the issue:
I added $tagList: [interestTags_bool_exp!] to the query function
I changed the query to interestTagsFromSenderId: {_or: $tagList}}
And changed the variable query to { "tagList": [{"tag": {"_eq": "dog"}}, {"tag": {"_eq": "apple"}}]}

Incorrectly selected data in the query

Only articles that contain the EmailMarketing tag are needed.
I'm probably doing the wrong search on the tag, since it's an array of values, not a single object, but I don't know how to do it right, I'm just learning graphql. Any help would be appreciated
query:
query {
enArticles {
title
previewText
tags(where: {name: "EmailMarketing"}){
name
}
}
}
result:
{
"data": {
"enArticles": [
{
"title": "title1",
"previewText": "previewText1",
"tags": [
{
"name": "EmailMarketing"
},
{
"name": "Personalization"
},
{
"name": "Advertising_campaign"
}
]
},
{
"title": "title2",
"previewText": "previewText2",
"tags": [
{
"name": "Marketing_strategy"
},
{
"name": "Marketing"
},
{
"name": "Marketing_campaign"
}
]
},
{
"title": "article 12",
"previewText": "article12",
"tags": []
}
]
}
}
I believe you first need to have coded an equality operator within your GraphQL schema. There's a good explanation of that here.
Once you add an equality operator - say, for example _eq - you can use it something like this:
query {
enArticles {
title
previewText
tags(where: {name: {_eq: "EmailMarketing"}}){
name
}
}
}
Specifically, you would need to create a filter and resolver.
The example here may help.

nuxt-apollo issues while pulling array of objects

I have been working with apollo-nuxt to query my graphql, but run into some weird issues while doing so. First of all this is my query:
{
getOrder(quantity: 2) {
id
createdAt
content {
amount
productId
}
}
}
which returns the following at /graphqli:
{
"data": {
"getOrder": [
{
"id": null,
"createdAt": 1592224281,
"content": [
{
"amount": 5,
"productId": "Salad"
},
{
"amount": 2,
"productId": "Water"
}
]
},
{
"id": null,
"createdAt": 1592224264,
"content": [
{
"amount": 5,
"productId": "Whine"
},
{
"amount": 3,
"productId": "Water"
}
]
}
]
}
}
this is as expected. Now using the same query in apollo (nuxt code):
<script>
import gql from 'graphql-tag'
export default {
apollo: {
orders: gql` query order {
orders: getOrder(quantity: 2) {
id
createdAt
content {
amount
productId
}
}
}`
},
...
will produce this result:
I cannot explain why the same query produces two different results. One with the two different objects in the array and the apollo one with two times the same object in an array. When adding more (by increasing the quantity) I just get more of the same object in the array. What am I missing here?
Your id for both orders is the same value (null) so Apollo ends up using the cache key for both orders (Order:null) and the orders field ends up referring to the same key twice. You need to fix your backend so that id is resolved correctly to a unique value for each Order.

GraphQL - How to get field types from the retrieved schema?

Knowing the schema (fetched via getIntrospectionQuery), how could I get the type of a particular field?
For example, say I run this query:
query {
User {
name
lastUpdated
friends {
name
}
}
}
and get this result:
{
"data": {
"User": [
{
"name": "alice",
"lastUpdated": "2018-02-03T17:22:49+00:00",
"friends": []
},
{
"name": "bob",
"lastUpdated": "2017-09-01T17:08:49+00:00",
"friends": [
{
"name": "eve"
}
]
}
]
}
}
I'd like to know the types of the fields and construct something like this:
{
"name": "String",
"lastUpdated": "timestamptz",
"friends": "[Friend]"
}
How could I do that without extra requests to the server?
After retrieving the schema, you can build it into a JSON object (if your graphql framework does not do it already for you).
Using a JSON parser, you can retrieve the the types of each field.
I will not enter into the detail, as it would depend on the technology your are using.

GraphQL query to cross reference data

Please find a basic simplified problem and a question below:
Monopoly Example
Data Types:
USER
name
houses (one-to-many)
STREET
name
HOUSE
street (one-to-one)
Note that in my data model there is no reference between user and streets (maybe monopoly wasn't the best example -.-)
Question:
A user can have several houses on different streets. How can I query a list of streets that a specific user has houses on?
Wanted Result:
{
"data": {
"User": {
"name": "The Hat",
"streets": [
{
name: "Bow Street"
},
{
name: "Oxford Street"
},
{
name: "Park Lane"
},
]
}
}
}
Is that possible?
Fetching relational data like that is typically handled by having nested fields in your query. The ability to traverse the data graph in a query is one of GraphQL's biggest benefits.
In general, this article about GraphQL APIs is a helpful resource to understand how it works.
Let's look at some different possible queries.
Query a list of streets that a specific user has houses on
query {
allStreets(filter: {
house: {
user: {
id: "user-id"
}
}
}) {
name
}
}
Here we make use of a relational filter passed in as an argument to query the streets that are related to a hours that is related to a specific user, which results in:
{
"data": {
"allStreets": [
{
"name": "Bow Street"
},
{
"name": "Oxford Street"
},
{
"name": "Park Lane"
}
]
}
}
We can see that we get back a list of streets. We could also include the house field in the allStreets query to obtain that information as well.
Query a specific user object and a list of streets that it has houses on
query {
User(id: "user-id") {
name
houses {
street {
name
}
}
}
}
Here we specify a user by id, so the top-level object of the result is a single user object. Additionally, we are getting back a list of streets that user has houses on:
{
"data": {
"User": {
"name": "The Hat",
"houses": [
{
"street": {
"name": "Bow Street"
}
},
{
"street": {
"name": "Oxford Street"
}
},
{
"street": {
"name": "Park Lane"
}
}
]
}
}
}
What's notable is that the structure of the response follows the structure of the query precisely.

Resources