# Paginating queries

The Eduflow API supports paginating lists of data through standard [GraphQL connections](https://graphql.org/learn/pagination/#end-of-list-counts-and-connections).

### Example

{% tabs %}
{% tab title="Page 1" %}
`first: 2` will pick the first 2 reviews from this Teacher review activity:

```graphql
{
  activity(id: "5572112e-66ad-45de-bd83-1332df79f51c") {
    ... on TeacherReviewActivity {
      title
      activityType
      reviews(first: 2) {
        pageInfo {
          hasPreviousPage
          hasNextPage
          endCursor
        }
        edges {
          node {
            createdAt
            modifiedAt
            answers {
              booleanAnswer
              scaleAnswer
              textAnswer
              comment
              scaleAnswerPercentage
            }
            givers {
              email
            }
            receivers {
              email
            }
          }
        }
      }
    }
  }
}

```

{% endtab %}

{% tab title="Response" %}
Response includes requested data and `endCursor` of `YXJyYXljb25uZWN0aW9uOjE=`, which we'll use in Page 2:

```javascript
{
  "data": {
    "activity": {
      "title": "Flow 1 - Activity 5 - Teacher's Perspective",
      "activityType": "TeacherReview",
      "reviews": {
        "pageInfo": {
          "hasPreviousPage": false,
          "hasNextPage": true,
          "endCursor": "YXJyYXljb25uZWN0aW9uOjE="
        },
        "edges": [
          {
            "node": {
              "createdAt": "2021-02-03T07:06:20.054270",
              "modifiedAt": "2021-02-03T07:06:20.054275",
              "answers": [
                {
                  "booleanAnswer": null,
                  "scaleAnswer": null,
                  "textAnswer": "Some awesome answer for question \"Question of type Text\" (a17d3ff4-25ac-4f15-bfde-8422112cf072) However media expert mind everything key shake manage clear until yes much realize professor defense begin national to authority among government seek performance probably compare role something image Congress next tree receive western wait bed memory dark person boy population size whom road they none spring information husband health officer past marriage officer where one success idea contain top become he case eight cell through rich late manager data every economic increase billion central almost.",
                  "comment": null,
                  "scaleAnswerPercentage": null
                },
                {
                  "booleanAnswer": null,
                  "scaleAnswer": 1,
                  "textAnswer": null,
                  "comment": null,
                  "scaleAnswerPercentage": 25
                },
                {
                  "booleanAnswer": false,
                  "scaleAnswer": null,
                  "textAnswer": null,
                  "comment": "Yard consumer subject plant every than education life.",
                  "scaleAnswerPercentage": null
                }
              ],
              "givers": [
                {
                  "email": "Geoff@example.edu"
                }
              ],
              "receivers": [
                {
                  "email": null
                }
              ]
            }
          },
          {
            "node": {
              "createdAt": "2021-02-03T00:06:20.095326",
              "modifiedAt": "2021-02-03T00:06:20.095335",
              "answers": [
                {
                  "booleanAnswer": null,
                  "scaleAnswer": null,
                  "textAnswer": "Some awesome answer for question \"Question of type Text\" (a17d3ff4-25ac-4f15-bfde-8422112cf072) Author easy herself treat budget majority recently theory onto argue foreign win situation shake sense certain opportunity coach picture family picture attack almost short should discover allow down while picture finish every tree watch across above consumer audience after building environmental look second identify live challenge edge establish why lawyer that white customer market idea our local when rich television still indeed seek investment ever attorney analysis why about major everybody culture expect what wonder.",
                  "comment": null,
                  "scaleAnswerPercentage": null
                },
                {
                  "booleanAnswer": null,
                  "scaleAnswer": 4,
                  "textAnswer": null,
                  "comment": null,
                  "scaleAnswerPercentage": 100
                },
                {
                  "booleanAnswer": true,
                  "scaleAnswer": null,
                  "textAnswer": null,
                  "comment": "In including wonder policy some piece scientist.",
                  "scaleAnswerPercentage": null
                }
              ],
              "givers": [
                {
                  "email": "Geoff@example.edu"
                }
              ],
              "receivers": [
                {
                  "email": null
                }
              ]
            }
          }
        ]
      }
    }
  }
}
```

{% endtab %}

{% tab title="Page 2" %}
Pass the first page's `endCursor` into `first`:

```graphql
{
  activity(id: "5572112e-66ad-45de-bd83-1332df79f51c") {
    ... on TeacherReviewActivity {
      title
      activityType
      reviews(first: 2, after: "YXJyYXljb25uZWN0aW9uOjE=") {
        pageInfo {
          hasPreviousPage
          hasNextPage
          endCursor
        }
        edges {
          node {
            createdAt
            modifiedAt
            answers {
              booleanAnswer
              scaleAnswer
              textAnswer
              comment
              scaleAnswerPercentage
            }
            givers {
              email
            }
            receivers {
              email
            }
          }
        }
      }
    }
  }
}

```

{% endtab %}

{% tab title="Response" %}

* Begins directly on the second page
* `hasPreviousPage` is now `true`
* New `endCursor` is `YXJyYXljb25uZWN0aW9uOjM=`, let's use it on Page 3:

```javascript
{
  "data": {
    "activity": {
      "title": "Flow 1 - Activity 5 - Teacher's Perspective",
      "activityType": "TeacherReview",
      "reviews": {
        "pageInfo": {
          "hasPreviousPage": true,
          "hasNextPage": true,
          "endCursor": "YXJyYXljb25uZWN0aW9uOjM="
        },
        "edges": [
          {
            "node": {
              "createdAt": "2021-02-03T09:12:20.137659",
              "modifiedAt": "2021-02-03T09:12:20.137664",
              "answers": [
                {
                  "booleanAnswer": null,
                  "scaleAnswer": null,
                  "textAnswer": "Some awesome answer for question \"Question of type Text\" (a17d3ff4-25ac-4f15-bfde-8422112cf072) Be station board find own rest either agreement account report investment personal form information fall rise guess site local father attorney season argue call along Congress crime watch again watch decide method mean leader because plan decision audience tonight kitchen by box carry serve we look who realize focus check create newspaper next room either event every business box section cup feel father direction college difficult garden computer production should side decision force issue send challenge return debate force production half lawyer walk inside positive that beautiful allow response land.",
                  "comment": null,
                  "scaleAnswerPercentage": null
                },
                {
                  "booleanAnswer": null,
                  "scaleAnswer": 4,
                  "textAnswer": null,
                  "comment": null,
                  "scaleAnswerPercentage": 100
                },
                {
                  "booleanAnswer": true,
                  "scaleAnswer": null,
                  "textAnswer": null,
                  "comment": "Reflect leader understand another management.",
                  "scaleAnswerPercentage": null
                }
              ],
              "givers": [
                {
                  "email": "Murphy@example.edu"
                }
              ],
              "receivers": [
                {
                  "email": null
                }
              ]
            }
          },
          {
            "node": {
              "createdAt": "2021-02-03T00:06:20.179206",
              "modifiedAt": "2021-02-03T00:06:20.179212",
              "answers": [
                {
                  "booleanAnswer": null,
                  "scaleAnswer": null,
                  "textAnswer": "Some awesome answer for question \"Question of type Text\" (a17d3ff4-25ac-4f15-bfde-8422112cf072) Feel artist star determine family trouble man enjoy turn medical list mouth itself together sense along than authority bag skin check simply heart assume issue by office though community read trial since success you TV worry your stuff security office provide oil push treatment area these early discussion even treatment general hope whole enjoy financial talk after health kitchen ready region area support meet next consumer federal street section traditional him garden crime anything ready thought western sometimes line chance nor anything can thing sense before available view us both attack lay show information form wind memory main program center rock value sense personal.",
                  "comment": null,
                  "scaleAnswerPercentage": null
                },
                {
                  "booleanAnswer": null,
                  "scaleAnswer": 4,
                  "textAnswer": null,
                  "comment": null,
                  "scaleAnswerPercentage": 100
                },
                {
                  "booleanAnswer": false,
                  "scaleAnswer": null,
                  "textAnswer": null,
                  "comment": "Five economic affect writer approach white.",
                  "scaleAnswerPercentage": null
                }
              ],
              "givers": [
                {
                  "email": "murphy@example.com"
                }
              ],
              "receivers": [
                {
                  "email": null
                }
              ]
            }
          }
        ]
      }
    }
  }
}
```

{% endtab %}

{% tab title="Page 3" %}
This time, for variety, let's just take `1`, and return different fields:

```graphql
{
  activity(id: "5572112e-66ad-45de-bd83-1332df79f51c") {
    ... on TeacherReviewActivity {
      title
      activityType
      reviews(first: 1, after: "YXJyYXljb25uZWN0aW9uOjM=") {
        pageInfo {
          endCursor
        }
        edges {
          node {
            reviewType
            createdAt
            modifiedAt
            answers {
              scaleAnswerPercentage
            }
            givers {
              email
            }
            receivers {
              email
            }
          }
        }
      }
    }
  }
}

```

Based on the query being adjust to `first: 1`, we should only see one item returned in page 3.
{% endtab %}

{% tab title="Response" %}

* Only shows the fields requested (fields don't need to be the same each time)
* Shows `reviewType`
* Only shows 1 result, per `first`

```javascript
{
  "data": {
    "activity": {
      "title": "Flow 1 - Activity 5 - Teacher's Perspective",
      "activityType": "TeacherReview",
      "reviews": {
        "pageInfo": {
          "endCursor": "YXJyYXljb25uZWN0aW9uOjQ="
        },
        "edges": [
          {
            "node": {
              "reviewType": "TeacherReview",
              "createdAt": "2021-02-03T09:36:20.221437",
              "modifiedAt": "2021-02-03T09:36:20.221441",
              "answers": [
                {
                  "scaleAnswerPercentage": null
                },
                {
                  "scaleAnswerPercentage": 125
                },
                {
                  "scaleAnswerPercentage": null
                }
              ],
              "givers": [
                {
                  "email": "murphy@example.edu"
                }
              ],
              "receivers": [
                {
                  "email": "michael@example.edu"
                }
              ]
            }
          }
        ]
      }
    }
  }
}
```

{% endtab %}
{% endtabs %}

The above example moves between 3 pages, passing the `endCursor` of the previous query into the `after` of the next page's.  The initial (first) page doesn't need any `after`. The final page alters the fields queried and changes the amount returned.

#### Bonus: Start at `last` item and travel backwards

{% tabs %}
{% tab title="Page 1" %}
`last: 2` instead of `first`:

```graphql
{
  activity(id: "5572112e-66ad-45de-bd83-1332df79f51c") {
    ... on TeacherReviewActivity {
      title
      activityType
      reviews(last: 2) {
        pageInfo {
          hasPreviousPage
          hasNextPage
          startCursor
        }
        edges {
          node {
            reviewType
            createdAt
            modifiedAt
            answers {
              scaleAnswerPercentage
            }
            givers {
              email
            }
            receivers {
              email
            }
          }
        }
      }
    }
  }
}

```

{% endtab %}

{% tab title="Response" %}

* Returns 2 items
* Last item
* `hasPreviousPage` is `true`
* `startCursor` of `YXJyYXljb25uZWN0aW9uOjQ=` will be used in `before` on the next page

```javascript
{
  "data": {
    "activity": {
      "title": "Flow 1 - Activity 5 - Teacher's Perspective",
      "activityType": "TeacherReview",
      "reviews": {
        "pageInfo": {
          "hasPreviousPage": true,
          "startCursor": "YXJyYXljb25uZWN0aW9uOjQ="
        },
        "edges": [
          {
            "node": {
              "reviewType": "TeacherReview",
              "createdAt": "2021-02-03T08:06:20.221437",
              "modifiedAt": "2021-02-03T08:06:20.221441",
              "answers": [
                {
                  "scaleAnswerPercentage": null
                },
                {
                  "scaleAnswerPercentage": 125
                },
                {
                  "scaleAnswerPercentage": null
                }
              ],
              "givers": [
                {
                  "email": "nick@example.edu"
                }
              ],
              "receivers": [
                {
                  "email": "michael@example.edu"
                }
              ]
            }
          },
          {
            "node": {
              "reviewType": "TeacherReview",
              "createdAt": "2021-02-03T08:06:20.261409",
              "modifiedAt": "2021-02-03T08:06:20.261414",
              "answers": [
                {
                  "scaleAnswerPercentage": null
                },
                {
                  "scaleAnswerPercentage": 125
                },
                {
                  "scaleAnswerPercentage": null
                }
              ],
              "givers": [
                {
                  "email": "nick@example.edu"
                }
              ],
              "receivers": [
                {
                  "email": null
                }
              ]
            }
          }
        ]
      }
    }
  }
}
```

{% endtab %}

{% tab title="Page 2" %}
Since we're moving backwards, we use `before`:

```graphql
{
  activity(id: "5572112e-66ad-45de-bd83-1332df79f51c") {
    ... on TeacherReviewActivity {
      title
      activityType
      reviews(last: 2, before: "YXJyYXljb25uZWN0aW9uOjU=") {
        pageInfo {
          hasPreviousPage
          startCursor
        }
        edges {
          node {
            reviewType
            createdAt
            modifiedAt
            answers {
              scaleAnswerPercentage
            }
            givers {
              email
            }
            receivers {
              email
            }
          }
        }
      }
    }
  }
}

```

{% endtab %}

{% tab title="Response" %}
Continue with cursor

```javascript
{
  "data": {
    "activity": {
      "title": "Flow 1 - Activity 5 - Teacher's Perspective",
      "activityType": "TeacherReview",
      "reviews": {
        "pageInfo": {
          "hasPreviousPage": true,
          "startCursor": "YXJyYXljb25uZWN0aW9uOjM="
        },
        "edges": [
          {
            "node": {
              "reviewType": "TeacherReview",
              "createdAt": "2021-02-03T07:06:20.179206",
              "modifiedAt": "2021-02-03T07:06:20.179212",
              "answers": [
                {
                  "scaleAnswerPercentage": null
                },
                {
                  "scaleAnswerPercentage": 100
                },
                {
                  "scaleAnswerPercentage": null
                }
              ],
              "givers": [
                {
                  "email": "geoff@example.edu"
                }
              ],
              "receivers": [
                {
                  "email": null
                }
              ]
            }
          },
          {
            "node": {
              "reviewType": "TeacherReview",
              "createdAt": "2021-02-03T07:06:20.221437",
              "modifiedAt": "2021-02-03T07:06:20.221441",
              "answers": [
                {
                  "scaleAnswerPercentage": null
                },
                {
                  "scaleAnswerPercentage": 125
                },
                {
                  "scaleAnswerPercentage": null
                }
              ],
              "givers": [
                {
                  "email": "geoff@example.edu"
                }
              ],
              "receivers": [
                {
                  "email": "nicholas@example.edu"
                }
              ]
            }
          }
        ]
      }
    }
  }
}
```

{% endtab %}
{% endtabs %}

### GraphQL Terms

| Term       | Description                                                                                                                                                                                                                                                                                       |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `first`    | For slicing, fetch the items at the beginning                                                                                                                                                                                                                                                     |
| `last`     | For slicing, beginning at last item                                                                                                                                                                                                                                                               |
| `after`    | Accepts a cursor ID of where to continue paginating                                                                                                                                                                                                                                               |
| `cursor`   | ID of the cursor, in Eduflow, sometimes equal to `pageInfo.endCursor`                                                                                                                                                                                                                             |
| `pageInfo` | <p>Structure containing cursor location, item count, previous/next page</p><ul><li><code>startCursor</code></li><li><code>endCursor</code>: Use this in the next page's <code>after:</code> to start on next page</li><li><code>hasPreviousPage</code></li><li><code>hasNextPage</code></li></ul> |
| `edges`    | List of containing `node`s (list of objects) of the connection                                                                                                                                                                                                                                    |
| `node`     | The object itself, e.g. `User`, `Activity`                                                                                                                                                                                                                                                        |

#### See also

* [GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm) on relay.dev ([archive.org](https://web.archive.org/web/20200423070245/https://relay.dev/graphql/connections.htm))
* [Pagination](https://graphql.org/learn/pagination/) on graphql.org ([archive.org](https://web.archive.org/web/20210110104322/https://graphql.org/learn/pagination/))
