How to use the "nextToken" parameter to test Pagination? - graphql

I am working with a sample of graphql query which I want to further bind to a FlatList object in a React-Native app. But I am still struggling to understand what I should pass on then nextToken parameter in order to get a slice of objects destined to a second page...
Tried to pass the next or last id or index, but it didn't work - it asks me to provide a valid nextToken, which I don't know what kind of data it is.
I'm running through AppSynch console.
My query:
query ListResources(
$nextTokenPlants: String = "Orange Tree"
$limitPlants: Int = 3
) {
listResources {
items {
id
name
Plants(limit: $limitPlants, nextToken:$nextTokenPlants) {
items {
id
name
filterName
description
bath
tea
insence
children
}
nextToken
}
}
nextToken
}
}
This is the result I get:
{
"data": {
"listResources": {
"items": [
{
"id": "361dee16-d567-41ed-b1d4-9baa4a7ffdcc",
"name": "Plantas",
"Plants": null
}
],
"nextToken": null
}
},
"errors": [
{
"path": [
"listResources",
"items",
0,
"Plants"
],
"data": null,
"errorType": "DynamoDB:UserIllegalArgumentException",
"errorInfo": null,
"locations": [
{
"line": 9,
"column": 7,
"sourceName": null
}
],
"message": "com.amazonaws.deepdish.common.pagination.InvalidPaginationTokenException: Invalid pagination token given."
}
]
}
I expected to get a list of 3 of the itens stored on "Plants", starting from the "Orange Tree" onwards... Could anyone pls shed some light on it?

nextToken is a String that you get in the response when you send a request, looks like
eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGdtYVZObHlaR3FSa3hDRnFVWWdFeEZDM0FMY1JRdE9UOEt2dWFLMExzcjJ3RlBPMGdpcC96bjQ5VjFOVElKUng1M0FBQUNlVENDQW5VR0NTcUdTSWIzRFFFSEJxQ0NBbVl3Z2dKaUFnRUFNSUlDV3dZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF4VEt5Myt3RUJuSzVSU2hsUUNBUkNBZ2dJc1lmdDk2WVVmQ053Tms2WGkxc3Z2bUgzSGFQZTdNTm1DQWhDcWJ5RFlydXZwTmR6WUNBQ0pJS1RZQlVWdk1xbU9EV2s2SVdLTzlqNmRhenNWZGZYTmFTQmxseE9yUS9BZWY0c2NpL1duWVUweWEyNCthZGQxcVNaMGZEWDZUdkJDak1XQjQ4QmhTQmxLejk2TFpiZ3pDN3dJTzVPRStFbUxHdVhRcURXcUpNZDM3Rm0yNUdiQVU1Tlg1YWVtWE1PbnVKSkZpTzA3U3ZhdUVZMWZwaXZCVU9pMHlxTVlIYk5PMkQ4aDZRVmQ4eW4yTXl3YU9UUHYwWFJZNitrakgvNGlyOWtrdlVXK1pvNFdOeDFBL2h1MlF4Z0lSczQ3d0xTT2NsaXk1Y3o0eFFzM2xqREhYL3M0TTVwT2phTCt0TGpYOUlWcGZCVW45bUgwWEw4ZEFkR0VZRGdjeWpMUHlPdWFnREVNMWR4M09neTg4NGJPclJ3VVgrRmM0UHpGekRqSHZjcjBGSVVXNEM2ZUxzYVRtRjNFakhLRk9ERllDWWkrQ01QNFg0a0dCdTFJQ3BLQjNJdEx2VTZHcUxNVDRMd3NJbkk4SVBhZm1MRnYxRTZDbWxxMnFKZ2wxY1BEVmR6MVFDc0Ezby9vR0VHUkI2VkJtc3VFSUFuOW10OVJzaWpyaklqUm5DQzlSWHA3NnA0WlhWanBJY0dSVU9GTktvZGNnMVpNbGV0a200clhBUGJacFZ5TDdkcnQyTXlEVERQd1crcjZsRHJUUVJJZzI4MEl3Y3ZkQzB1RWRrb0hqTlZPR0kwSWxsSnZ5RjRWTCtNNzRuWXcwNVNSWllJODdGcGdzR21LZjRvWVA1VG9temRVUUR0YWkrZVRJcUxGRjlGYzk0UUNwZlYrVlpmeVU0Mk4yTnRtNi9MYUhrZ08zdGRTUHN1bGhQWVRuMGRQNU5aWG5pODU1eGZyL1N2dDQ2VU0xb3I2UEE9PSJ9
and it has nothing to do with your table keys.
Let me explain now how does it work:
When you send the request for the first time, you don't send nextToken since you don't have it and then you get the first portion of your data.
When you receive that first portion, if there exist more data, you get nextToken in the response.
Now, you have nextToken, you send another request to get the 2nd portion of your data. You should send that token in the request, so your backend knows from where to start.
You get your 2nd portion of data and a new nextToken if there is still some data to fetch (then you need to repeat step 2) or null in nextToken if there is no more data.
I hope that it's clear now

Related

Apollo Server federation resolvers: how to gracefully handle entity not found?

When using GraphQL federated resolvers to resolve an array, and one of the resolved items cannot be found:
Observed behaviour: null data returned for entire query, no error message.
Desired behaviour: the item which cannot be resolved is silently dropped from results array.
What works
Using Apollo Server federation, we are successfully able to resolve the following query:
query {
products {
name
reviews {
id
score
}
}
}
where products comes from the Product subgraph and score is resolved by the Review subgraph.
This works fine when all the review ids passed to the Review subgraph are resolvable.
Our Problem
Sometimes the Review subgraph deems that a review should not be returned. The business case could be, for example, it was automatically marked as spam and is blocked until a manual check is done.
In this situation, the Review subgraph returns null for this ID. Example query:
query {
_entities(representations: [
{id: 1, __typename: "Review"},
{id: 2, __typename: "Review"}
]) {
...on Review {
id
score
}
}
}
Result
{
"data": {
"_entities": [
{
"id": "1",
"score": "94"
},
null
]
}
}
When this happens, we would want the federated results to contain the Product and only review 1, the non-resolveable review id 2 having been dropped from the array. Like this:
{
"data": {
"products": {
"name": "Phone cover",
"reviews": [
{
"id": "1",
"score": "94"
}
]
}
}
}
However, Apollo Server returns null for the entire query, with no error message:
{
"data": null
}
Is this expected behaviour? Is there any way to gain the result I want, or otherwise control how Apollo reacts when one item in a reference array is not resolved?

How to handle JSON array response while using APIConsumer?

Using the APIConsumer contract we can feed data from API to the smart contract.
Eg: If the server response is:
{
"RAW":{"ETH":{"USD":{"VOLUME24HOUR": 10000,}}}
}
Then, data can be obtained as:
request.add("get", URL);
request.add("path", "RAW.ETH.USD.VOLUME24HOUR");
Similarly, If the server response contains some JSON array,
Eg:
{
"date":"530934083405834",
"results": [
{
"id": 9865,
"rank":1
},
{
"id": 9869,
"rank": 2
},
{
"id": 9866,
"rank": 3
}
]}
Then in this case is there a way to get the id of the rank 1 i.e results[0]["id"]?
To get results[0]["id"] your path in the request needs to be
request.add("path", "results.0.id");

How can i provide a a value for an argument in GraphQL?

I'm very new to GraphQL, and i'm trying to perform some example queries to this graph. In particular i'm trying the User schema.
According to that documentation, the schema is the following:
id: ID!
liquidityPositions: [LiquidityPosition!]
usdSwapped: BigDecimal!
And here is query i tried:
{
user (where: {id: "0x7c9C48b7cBEbBDA3268435F20c81f15A538C566C"}) {
id
liquidityPositions
usdSwapped
}
}
This query fails, i keep getting the following response:
{
"errors": [
{
"locations": [
{
"line": 0,
"column": 0
}
],
"message": "No value provided for required argument: `id`"
}
]
}
How can i provide the id field and where am i supposed to provide it? Thanks in advance!
You've got a couple of problems with that query. First, to get a user by id, remove the "where" and curly braces from your query. Secondly, the liquityPositions field needs a selection of subfields. Like so:
{
user (id: "0x7c9C48b7cBEbBDA3268435F20c81f15A538C566C") {
id
liquidityPositions {
id
}
usdSwapped
}
}
That website you linked to will show you errors with your query so you can interactively learn more about what is supported.
I would also suggest running through the introduction to GraphQL here: https://graphql.org/learn/ to get a handle on how things are done.

couchDB- complex query on a view

I am using cloudantDB and want to query a view which looks like this
function (doc) {
if(doc.name !== undefined){
emit([doc.name, doc.age], doc);
}
what should be the correct way to get a result if I have a list of names(I will be using option 'keys=[]' for it) and a range of age(for which startkey and endkey should be used)
example: I want to get persons having name "john" or "mark" or "joseph" or "santosh" and lie between age limit 20 to 30.
If i go for list of names, query should be keys=["john", ....]
and if I go for age query should use startkey and endkey
I want to do both :)
Thanks
Unfortunately, you can't do so. Using the keys parameter query the documents with the specified key. For example, you can't only send keys=["John","Mark"]&startkey=[null,20]&endkey=[{},30]. This query would only and ONLY return the document having the name John and Mark with a null age.
In your question you specified CouchDB but if you are using Cloudant, index query might be interesting for you.
You could have something like that :
{
"selector": {
"$and": [
{
"name": {
"$in":["Mark","John"]
}
},
{
"year": {
"$gt": 20,
"$lt": 30
}
}
]
},
"fields": [
"name",
"age"
]
}
As for CouchDB, you need to either separate your request (1 request for the age and 1 for the people) or you do the filtering locally.

Error while accessing nested JSON object

This is a sample row in my RethinkDB table.
{
"a1": "val1" ,
"a2": "val2" ,
"a3": "val3" ,
"a4": "val4" ,
"part": [
{
"id": "reql" ,
"position": "student"
} ,
{
"id": "sdsadda" ,
"position": "officer"
}
] ,
"a5": "val5"
}
I want to access a nested json object but I get the error e: Cannot perform bracket on a non-object non-sequence "string"
I need the entire row in the output for rows matching id to "reql"
This is my query
r.db('dbname').table('tablename').filter(r.row('part').contains(function(product) {
return product('id').eq("reql");
}))
This query worked before .It doesn't right now.
You'd get that error if you'd somehow ended up with an element in your part array that's a string instead of an object. Try running .filter(r.row('part').contains(function(product) { return product.typeOf().ne('OBJECT'); }), that should return all the rows that have a string in the part array.
Regarding your comment #Puja, I think this should do it for you:
r.db('dbname').table('tablename').filter(function(d){
d("part").typeOf().eq("ARRAY");
}).filter(r.row('part').contains(function(d) {
return d('id').eq("reql");
}))
Although, this is less efficient than #mlucy's answer, and you should definitely just do the one pass over your dataset to clean it up by fixing all the documents where part: STRING.

Resources