How to paginate a list of posts belonging to a specific category in GatsbyJS












0















I have developed a blog with Gatsby JS and I managed to add categories to each markdown file so that I can create pages by querying a specific category and list all the posts related to that category.
Now, I'm trying to add pagination to avoid an infinite list of posts inside each category page.



I have been following the official guide here: https://www.gatsbyjs.org/docs/adding-pagination/



And this is the code I came up with:



gatsby-node.js



const path = require('path')
const _ = require("lodash")
const { createFilePath } = require("gatsby-source-filesystem")

exports.createPages = ({actions, graphql}) => {
const {createPage} = actions

const articleTemplate = path.resolve(`src/templates/article.js`)
const categoryTemplate = path.resolve("src/templates/category.js")

return new Promise((resolve, reject) => {
resolve(
graphql(
`
{
allMarkdownRemark(
sort: { order: DESC, fields: [frontmatter___date] }
limit: 2000
) {
edges {
node {
html
id
frontmatter {
path
title
categories
}
}
}
}
}

`).then(result => {
if (result.errors) {
reject(result.errors)
}

const articles = result.data.allMarkdownRemark.edges
const articlesPerPage = 6
const numPages = Math.ceil(articles.length / articlesPerPage)

//Creating a page for each article
articles.forEach(({ node }) => {
createPage({
path: node.frontmatter.path,
component: articleTemplate,
//context: {}, // additional data can be passed via context
})
})

// Categories pages:
let categories =
// Iterate through each article, putting all found categories into `categories`
_.each(articles, edge => {
if (_.get(edge, "node.frontmatter.categories")) {
categories = categories.concat(edge.node.frontmatter.categories)
}
})


Array.from({ length: numPages }).forEach((category, _, i) => {
createPage({
path: i === 0 ? `/${_.kebabCase(category)}/` : `/${_.kebabCase(category)}/${i + 1}`,
component: categoryTemplate,
context: {
limit: articlesPerPage,
skip: i * articlesPerPage,
category,
},
})
})
})
)
})


/templates/categories.js



import React from "react"
import PropTypes from "prop-types"
import Layout from '../layouts/layout'
import ArticleCard from '../components/articles/articlecard'

// Components
import { Link, graphql } from "gatsby"

const _ = require("lodash")

const Categories = ({ pageContext, data }) => {
const { category } = pageContext
const { edges } = data.allMarkdownRemark

return (
<Layout>
<section class="hero is-info is-medium has-text-centered">
<div class="hero-body">
<div class="container">
<h1 class="title is-top">
{category}
</h1>
</div>
</div>
</section>
<div class="section">
<div class="container">
<div class="columns is-multiline">
{edges.map(({ node }) => {
const { path, title, date } = node.frontmatter
return (
<div class="column is-half">
<div class="card">
<div class="card-header">
<p class="card-header-content">{date}</p>
</div>
<div class="card-content">
<Link to={_.kebabCase(category)}><span class="tag is-success has-padding">{category}</span></Link>
<Link to={path}>
<h2 class="title is-4">{title}</h2>
</Link>
</div>
<div class="card-footer">
<div class="card-footer-item"><Link to={path}><div class="button is-success is-inverted is-fullwidth">Read</div></Link></div>
<div class="card-footer-item"><Link to={path}><div class="button is-info is-inverted is-fullwidth">Share on Linkedin</div></Link></div>
</div>
</div>
</div>
)
})}
</div>
</div>
</div>
</Layout>
)
}

Categories.propTypes = {
pageContext: PropTypes.shape({
category: PropTypes.string.isRequired,
}),
data: PropTypes.shape({
allMarkdownRemark: PropTypes.shape({
totalCount: PropTypes.number.isRequired,
edges: PropTypes.arrayOf(
PropTypes.shape({
node: PropTypes.shape({
frontmatter: PropTypes.shape({
path: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
}),
}),
}).isRequired
),
}),
}),
}

export default Categories

export const pageQuery = graphql`
query($skip: Int!, $limit: Int!, $category: String) {
allMarkdownRemark(
sort: { fields: [frontmatter___date], order: DESC }
filter: { frontmatter: { categories: { in: [$category] } } }
limit: $limit
skip: $skip
) {
totalCount
edges {
node {
frontmatter {
title
path
date(formatString: "MMMM DD, YYYY")
}
}
}
}
}
`


This does not work and it is now throwing the error: error gatsby-node.js returned an error, TypeError: _.kebabCase is not a function



However kebabCase was used smoothly before modifying the query to add pagination, so I don't think the problem is actually there.



Does anyone have any clue?



Thank you!










share|improve this question



























    0















    I have developed a blog with Gatsby JS and I managed to add categories to each markdown file so that I can create pages by querying a specific category and list all the posts related to that category.
    Now, I'm trying to add pagination to avoid an infinite list of posts inside each category page.



    I have been following the official guide here: https://www.gatsbyjs.org/docs/adding-pagination/



    And this is the code I came up with:



    gatsby-node.js



    const path = require('path')
    const _ = require("lodash")
    const { createFilePath } = require("gatsby-source-filesystem")

    exports.createPages = ({actions, graphql}) => {
    const {createPage} = actions

    const articleTemplate = path.resolve(`src/templates/article.js`)
    const categoryTemplate = path.resolve("src/templates/category.js")

    return new Promise((resolve, reject) => {
    resolve(
    graphql(
    `
    {
    allMarkdownRemark(
    sort: { order: DESC, fields: [frontmatter___date] }
    limit: 2000
    ) {
    edges {
    node {
    html
    id
    frontmatter {
    path
    title
    categories
    }
    }
    }
    }
    }

    `).then(result => {
    if (result.errors) {
    reject(result.errors)
    }

    const articles = result.data.allMarkdownRemark.edges
    const articlesPerPage = 6
    const numPages = Math.ceil(articles.length / articlesPerPage)

    //Creating a page for each article
    articles.forEach(({ node }) => {
    createPage({
    path: node.frontmatter.path,
    component: articleTemplate,
    //context: {}, // additional data can be passed via context
    })
    })

    // Categories pages:
    let categories =
    // Iterate through each article, putting all found categories into `categories`
    _.each(articles, edge => {
    if (_.get(edge, "node.frontmatter.categories")) {
    categories = categories.concat(edge.node.frontmatter.categories)
    }
    })


    Array.from({ length: numPages }).forEach((category, _, i) => {
    createPage({
    path: i === 0 ? `/${_.kebabCase(category)}/` : `/${_.kebabCase(category)}/${i + 1}`,
    component: categoryTemplate,
    context: {
    limit: articlesPerPage,
    skip: i * articlesPerPage,
    category,
    },
    })
    })
    })
    )
    })


    /templates/categories.js



    import React from "react"
    import PropTypes from "prop-types"
    import Layout from '../layouts/layout'
    import ArticleCard from '../components/articles/articlecard'

    // Components
    import { Link, graphql } from "gatsby"

    const _ = require("lodash")

    const Categories = ({ pageContext, data }) => {
    const { category } = pageContext
    const { edges } = data.allMarkdownRemark

    return (
    <Layout>
    <section class="hero is-info is-medium has-text-centered">
    <div class="hero-body">
    <div class="container">
    <h1 class="title is-top">
    {category}
    </h1>
    </div>
    </div>
    </section>
    <div class="section">
    <div class="container">
    <div class="columns is-multiline">
    {edges.map(({ node }) => {
    const { path, title, date } = node.frontmatter
    return (
    <div class="column is-half">
    <div class="card">
    <div class="card-header">
    <p class="card-header-content">{date}</p>
    </div>
    <div class="card-content">
    <Link to={_.kebabCase(category)}><span class="tag is-success has-padding">{category}</span></Link>
    <Link to={path}>
    <h2 class="title is-4">{title}</h2>
    </Link>
    </div>
    <div class="card-footer">
    <div class="card-footer-item"><Link to={path}><div class="button is-success is-inverted is-fullwidth">Read</div></Link></div>
    <div class="card-footer-item"><Link to={path}><div class="button is-info is-inverted is-fullwidth">Share on Linkedin</div></Link></div>
    </div>
    </div>
    </div>
    )
    })}
    </div>
    </div>
    </div>
    </Layout>
    )
    }

    Categories.propTypes = {
    pageContext: PropTypes.shape({
    category: PropTypes.string.isRequired,
    }),
    data: PropTypes.shape({
    allMarkdownRemark: PropTypes.shape({
    totalCount: PropTypes.number.isRequired,
    edges: PropTypes.arrayOf(
    PropTypes.shape({
    node: PropTypes.shape({
    frontmatter: PropTypes.shape({
    path: PropTypes.string.isRequired,
    title: PropTypes.string.isRequired,
    }),
    }),
    }).isRequired
    ),
    }),
    }),
    }

    export default Categories

    export const pageQuery = graphql`
    query($skip: Int!, $limit: Int!, $category: String) {
    allMarkdownRemark(
    sort: { fields: [frontmatter___date], order: DESC }
    filter: { frontmatter: { categories: { in: [$category] } } }
    limit: $limit
    skip: $skip
    ) {
    totalCount
    edges {
    node {
    frontmatter {
    title
    path
    date(formatString: "MMMM DD, YYYY")
    }
    }
    }
    }
    }
    `


    This does not work and it is now throwing the error: error gatsby-node.js returned an error, TypeError: _.kebabCase is not a function



    However kebabCase was used smoothly before modifying the query to add pagination, so I don't think the problem is actually there.



    Does anyone have any clue?



    Thank you!










    share|improve this question

























      0












      0








      0








      I have developed a blog with Gatsby JS and I managed to add categories to each markdown file so that I can create pages by querying a specific category and list all the posts related to that category.
      Now, I'm trying to add pagination to avoid an infinite list of posts inside each category page.



      I have been following the official guide here: https://www.gatsbyjs.org/docs/adding-pagination/



      And this is the code I came up with:



      gatsby-node.js



      const path = require('path')
      const _ = require("lodash")
      const { createFilePath } = require("gatsby-source-filesystem")

      exports.createPages = ({actions, graphql}) => {
      const {createPage} = actions

      const articleTemplate = path.resolve(`src/templates/article.js`)
      const categoryTemplate = path.resolve("src/templates/category.js")

      return new Promise((resolve, reject) => {
      resolve(
      graphql(
      `
      {
      allMarkdownRemark(
      sort: { order: DESC, fields: [frontmatter___date] }
      limit: 2000
      ) {
      edges {
      node {
      html
      id
      frontmatter {
      path
      title
      categories
      }
      }
      }
      }
      }

      `).then(result => {
      if (result.errors) {
      reject(result.errors)
      }

      const articles = result.data.allMarkdownRemark.edges
      const articlesPerPage = 6
      const numPages = Math.ceil(articles.length / articlesPerPage)

      //Creating a page for each article
      articles.forEach(({ node }) => {
      createPage({
      path: node.frontmatter.path,
      component: articleTemplate,
      //context: {}, // additional data can be passed via context
      })
      })

      // Categories pages:
      let categories =
      // Iterate through each article, putting all found categories into `categories`
      _.each(articles, edge => {
      if (_.get(edge, "node.frontmatter.categories")) {
      categories = categories.concat(edge.node.frontmatter.categories)
      }
      })


      Array.from({ length: numPages }).forEach((category, _, i) => {
      createPage({
      path: i === 0 ? `/${_.kebabCase(category)}/` : `/${_.kebabCase(category)}/${i + 1}`,
      component: categoryTemplate,
      context: {
      limit: articlesPerPage,
      skip: i * articlesPerPage,
      category,
      },
      })
      })
      })
      )
      })


      /templates/categories.js



      import React from "react"
      import PropTypes from "prop-types"
      import Layout from '../layouts/layout'
      import ArticleCard from '../components/articles/articlecard'

      // Components
      import { Link, graphql } from "gatsby"

      const _ = require("lodash")

      const Categories = ({ pageContext, data }) => {
      const { category } = pageContext
      const { edges } = data.allMarkdownRemark

      return (
      <Layout>
      <section class="hero is-info is-medium has-text-centered">
      <div class="hero-body">
      <div class="container">
      <h1 class="title is-top">
      {category}
      </h1>
      </div>
      </div>
      </section>
      <div class="section">
      <div class="container">
      <div class="columns is-multiline">
      {edges.map(({ node }) => {
      const { path, title, date } = node.frontmatter
      return (
      <div class="column is-half">
      <div class="card">
      <div class="card-header">
      <p class="card-header-content">{date}</p>
      </div>
      <div class="card-content">
      <Link to={_.kebabCase(category)}><span class="tag is-success has-padding">{category}</span></Link>
      <Link to={path}>
      <h2 class="title is-4">{title}</h2>
      </Link>
      </div>
      <div class="card-footer">
      <div class="card-footer-item"><Link to={path}><div class="button is-success is-inverted is-fullwidth">Read</div></Link></div>
      <div class="card-footer-item"><Link to={path}><div class="button is-info is-inverted is-fullwidth">Share on Linkedin</div></Link></div>
      </div>
      </div>
      </div>
      )
      })}
      </div>
      </div>
      </div>
      </Layout>
      )
      }

      Categories.propTypes = {
      pageContext: PropTypes.shape({
      category: PropTypes.string.isRequired,
      }),
      data: PropTypes.shape({
      allMarkdownRemark: PropTypes.shape({
      totalCount: PropTypes.number.isRequired,
      edges: PropTypes.arrayOf(
      PropTypes.shape({
      node: PropTypes.shape({
      frontmatter: PropTypes.shape({
      path: PropTypes.string.isRequired,
      title: PropTypes.string.isRequired,
      }),
      }),
      }).isRequired
      ),
      }),
      }),
      }

      export default Categories

      export const pageQuery = graphql`
      query($skip: Int!, $limit: Int!, $category: String) {
      allMarkdownRemark(
      sort: { fields: [frontmatter___date], order: DESC }
      filter: { frontmatter: { categories: { in: [$category] } } }
      limit: $limit
      skip: $skip
      ) {
      totalCount
      edges {
      node {
      frontmatter {
      title
      path
      date(formatString: "MMMM DD, YYYY")
      }
      }
      }
      }
      }
      `


      This does not work and it is now throwing the error: error gatsby-node.js returned an error, TypeError: _.kebabCase is not a function



      However kebabCase was used smoothly before modifying the query to add pagination, so I don't think the problem is actually there.



      Does anyone have any clue?



      Thank you!










      share|improve this question














      I have developed a blog with Gatsby JS and I managed to add categories to each markdown file so that I can create pages by querying a specific category and list all the posts related to that category.
      Now, I'm trying to add pagination to avoid an infinite list of posts inside each category page.



      I have been following the official guide here: https://www.gatsbyjs.org/docs/adding-pagination/



      And this is the code I came up with:



      gatsby-node.js



      const path = require('path')
      const _ = require("lodash")
      const { createFilePath } = require("gatsby-source-filesystem")

      exports.createPages = ({actions, graphql}) => {
      const {createPage} = actions

      const articleTemplate = path.resolve(`src/templates/article.js`)
      const categoryTemplate = path.resolve("src/templates/category.js")

      return new Promise((resolve, reject) => {
      resolve(
      graphql(
      `
      {
      allMarkdownRemark(
      sort: { order: DESC, fields: [frontmatter___date] }
      limit: 2000
      ) {
      edges {
      node {
      html
      id
      frontmatter {
      path
      title
      categories
      }
      }
      }
      }
      }

      `).then(result => {
      if (result.errors) {
      reject(result.errors)
      }

      const articles = result.data.allMarkdownRemark.edges
      const articlesPerPage = 6
      const numPages = Math.ceil(articles.length / articlesPerPage)

      //Creating a page for each article
      articles.forEach(({ node }) => {
      createPage({
      path: node.frontmatter.path,
      component: articleTemplate,
      //context: {}, // additional data can be passed via context
      })
      })

      // Categories pages:
      let categories =
      // Iterate through each article, putting all found categories into `categories`
      _.each(articles, edge => {
      if (_.get(edge, "node.frontmatter.categories")) {
      categories = categories.concat(edge.node.frontmatter.categories)
      }
      })


      Array.from({ length: numPages }).forEach((category, _, i) => {
      createPage({
      path: i === 0 ? `/${_.kebabCase(category)}/` : `/${_.kebabCase(category)}/${i + 1}`,
      component: categoryTemplate,
      context: {
      limit: articlesPerPage,
      skip: i * articlesPerPage,
      category,
      },
      })
      })
      })
      )
      })


      /templates/categories.js



      import React from "react"
      import PropTypes from "prop-types"
      import Layout from '../layouts/layout'
      import ArticleCard from '../components/articles/articlecard'

      // Components
      import { Link, graphql } from "gatsby"

      const _ = require("lodash")

      const Categories = ({ pageContext, data }) => {
      const { category } = pageContext
      const { edges } = data.allMarkdownRemark

      return (
      <Layout>
      <section class="hero is-info is-medium has-text-centered">
      <div class="hero-body">
      <div class="container">
      <h1 class="title is-top">
      {category}
      </h1>
      </div>
      </div>
      </section>
      <div class="section">
      <div class="container">
      <div class="columns is-multiline">
      {edges.map(({ node }) => {
      const { path, title, date } = node.frontmatter
      return (
      <div class="column is-half">
      <div class="card">
      <div class="card-header">
      <p class="card-header-content">{date}</p>
      </div>
      <div class="card-content">
      <Link to={_.kebabCase(category)}><span class="tag is-success has-padding">{category}</span></Link>
      <Link to={path}>
      <h2 class="title is-4">{title}</h2>
      </Link>
      </div>
      <div class="card-footer">
      <div class="card-footer-item"><Link to={path}><div class="button is-success is-inverted is-fullwidth">Read</div></Link></div>
      <div class="card-footer-item"><Link to={path}><div class="button is-info is-inverted is-fullwidth">Share on Linkedin</div></Link></div>
      </div>
      </div>
      </div>
      )
      })}
      </div>
      </div>
      </div>
      </Layout>
      )
      }

      Categories.propTypes = {
      pageContext: PropTypes.shape({
      category: PropTypes.string.isRequired,
      }),
      data: PropTypes.shape({
      allMarkdownRemark: PropTypes.shape({
      totalCount: PropTypes.number.isRequired,
      edges: PropTypes.arrayOf(
      PropTypes.shape({
      node: PropTypes.shape({
      frontmatter: PropTypes.shape({
      path: PropTypes.string.isRequired,
      title: PropTypes.string.isRequired,
      }),
      }),
      }).isRequired
      ),
      }),
      }),
      }

      export default Categories

      export const pageQuery = graphql`
      query($skip: Int!, $limit: Int!, $category: String) {
      allMarkdownRemark(
      sort: { fields: [frontmatter___date], order: DESC }
      filter: { frontmatter: { categories: { in: [$category] } } }
      limit: $limit
      skip: $skip
      ) {
      totalCount
      edges {
      node {
      frontmatter {
      title
      path
      date(formatString: "MMMM DD, YYYY")
      }
      }
      }
      }
      }
      `


      This does not work and it is now throwing the error: error gatsby-node.js returned an error, TypeError: _.kebabCase is not a function



      However kebabCase was used smoothly before modifying the query to add pagination, so I don't think the problem is actually there.



      Does anyone have any clue?



      Thank you!







      node.js reactjs pagination graphql gatsby






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 24 '18 at 10:01









      GiuliaGiulia

      95111




      95111
























          0






          active

          oldest

          votes











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53457058%2fhow-to-paginate-a-list-of-posts-belonging-to-a-specific-category-in-gatsbyjs%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53457058%2fhow-to-paginate-a-list-of-posts-belonging-to-a-specific-category-in-gatsbyjs%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Wiesbaden

          Marschland

          Dieringhausen