Skip to content

Instantly share code, notes, and snippets.

@saleebm
Last active February 16, 2020 20:55
Show Gist options
  • Select an option

  • Save saleebm/8f8838c35c6c936635f6bf7efc0b16d3 to your computer and use it in GitHub Desktop.

Select an option

Save saleebm/8f8838c35c6c936635f6bf7efc0b16d3 to your computer and use it in GitHub Desktop.
Pagination woes
import { useQuery } from "@apollo/react-hooks";
import { NetworkStatus } from "@apollo/client";
import gql from "graphql-tag";
import ErrorMessage from "./ErrorMessage";
export const ALL_POSTS_QUERY = gql`
query GET_ALL_PRODUCTS_PAGES(
$first: Int
$after: String
$last: Int
$before: String
) {
products(first: $first, after: $after, last: $last, before: $before) {
pageInfo {
endCursor
startCursor
hasNextPage
hasPreviousPage
}
edges {
cursor
node {
name
productId
}
}
}
}
`;
const allPostsQueryVars = {
first: 10
};
export default function PostList() {
const { loading, error, data, fetchMore, networkStatus } = useQuery(
ALL_POSTS_QUERY,
{
variables: allPostsQueryVars,
// Setting this value to true will make the component rerender when
// the "networkStatus" changes, so we are able to know if it is fetching
// more data
notifyOnNetworkStatusChange: true
}
);
const loadingMorePosts = networkStatus === NetworkStatus.fetchMore;
const loadMorePosts = () => {
fetchMore({
variables: {
first: 10,
last: null,
after: data["products"]?.pageInfo?.endCursor
},
updateQuery: (previousResult, { fetchMoreResult }) => {
if (!fetchMoreResult) return previousResult;
const newEdges = fetchMoreResult.products?.edges;
const pageInfo = fetchMoreResult.products?.pageInfo;
return newEdges?.length && previousResult?.products && pageInfo
? {
products: {
__typename: previousResult.products?.__typename,
edges: [...newEdges],
pageInfo
}
}
: previousResult;
}
});
};
const loadLessPosts = () => {
fetchMore({
variables: {
first: null,
last: 10,
before: data["products"]?.pageInfo?.startCursor
},
updateQuery: (previousResult, { fetchMoreResult }) => {
if (!fetchMoreResult) return previousResult;
const newEdges = fetchMoreResult.products?.edges;
const pageInfo = fetchMoreResult.products?.pageInfo;
return newEdges?.length && previousResult?.products && pageInfo
? {
products: {
__typename: previousResult.products?.__typename,
edges: [...newEdges],
pageInfo
}
}
: previousResult;
}
});
};
if (error) return <ErrorMessage message="Error loading posts." />;
if (loading && !loadingMorePosts) return <div>Loading</div>;
return (
<section>
{data?.products?.edges?.map(edge => (
<div key={edge.node.id}>{edge.node.name}</div>
))}
{data && data["products"]?.pageInfo?.hasNextPage && (
<button onClick={() => loadMorePosts()} disabled={loadingMorePosts}>
{loadingMorePosts ? "Loading..." : "Show More"}
</button>
)}
{data && data["products"]?.pageInfo?.hasPreviousPage && (
<button onClick={() => loadLessPosts()} disabled={loadingMorePosts}>
{loadingMorePosts ? "Loading..." : "Show Less"}
</button>
)}
<style jsx>{`
section {
padding-bottom: 20px;
}
li {
display: block;
margin-bottom: 10px;
}
div {
align-items: center;
display: flex;
}
a {
font-size: 14px;
margin-right: 10px;
text-decoration: none;
padding-bottom: 0;
border: 0;
}
span {
font-size: 14px;
margin-right: 5px;
}
ul {
margin: 0;
padding: 0;
}
button:before {
align-self: center;
border-style: solid;
border-width: 6px 4px 0 4px;
border-color: #ffffff transparent transparent transparent;
content: "";
height: 0;
margin-right: 5px;
width: 0;
}
`}</style>
</section>
);
}
@saleebm
Copy link
Author

saleebm commented Feb 16, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment