I am building an application using Next.Js and Fauna where when a user visits the /accounts
route, it fetches Next.js API route /api/fauna/accounts
which makes a query to Fauna to get all the accounts the user owns then returns that response to the page and renders the data in a table.
Fetch inside /accounts
looks like so:
function Accounts() {
const [data, setData] = useState(null)
useEffect(() => {
fetch('api/accounts')
.then((res) => res.json())
.then((data) => {
setData(data)
})
}, [])
return (
<Table>
{...data}
</Table>
)
}
The response inside /api/fauna/accounts
returns an "after" cursor used for pagination. This is what the response looks like on the server inside /api/fauna/accounts
{
after: [
Time("2022-03-08T15:59:43.284410Z"),
Ref(Collection("accounts"), "325579003214692417"),
Ref(Collection("accounts"), "325579003214692417")
],
data: [...]
}
However, when that response is sent back to the /accounts
route, the "after" cursor is formatted completely differently than on the server which makes it difficult to paginate with. The response for the "after" cursor looks like this:
{
after: [
{ "@ts": "2022-03-08T15:49:23.686204Z" },
{
"@ref": {
id: "325578353522245700",
collection: { "@ref": { id: "accounts", collection: { "@ref": { id: "collections" } } } }
}
},
{
"@ref": {
id: "325578353522245700",
collection: { "@ref": { id: "accounts", collection: { "@ref": { id: "collections" } } } }
}
}
],
data: [...]
}
How do I paginate to the next page when the "after" cursor is formated like so?
The format that you're seeing is Fauna's wire protocol. JSON doesn't handle embedded objects like References (among other complex response values), so those get serialized in a way that can be round-tripped.
The JavaScript driver includes a utility library called _json.js
, which can take care of reconstituting the original cursor value:
const faunadb = require('faunadb')
const json = require('faunadb/src/_json')
const q = faunadb.query
// assuming response contains the wire protocol data from a pagination query
const deserialized = json.parseJSON(response)
// then you can include the `after` field in a subsequent query
const response2 = client.query(
q.Paginate(
q.Match(q.Index("your_index"), [<terms>]),
{
after: deserialized.after
}
)
)
.then(res => console.log(res))
.catch(err => console.err("Error:", err))