'Sorting the order of categories in navbar using Gatsby JS

I have a dynamic navbar that I implemented using graphql. I manage to get the categories by using distinct and setting the field to frontmatter___category then using .map(). However, graphql returns the categories in an alphabetical order but I want to sort their order. I am thinking of creating an index.md per category that could be used to sort them but I don't know how I could do that.

Using the distinct field, here is how I map through my categories and create the navbar (I'm using antd):

<Menu>
  {data[section]['distinct'].map((category) =>(
    <SubMenu 
      key={category} 
      title={category.replace('-', ' ')}
      style={{
        fontWeight: 700,
        maxWidth: 250,
      }}
    >
      {checkCategory(category)} //get the MD files that belongs to this category
    </SubMenu>
  ))}
</Menu>

Here is my query:

categoryA: allMdx(
  sort: {fields: frontmatter___order, order: ASC}
  filter: {frontmatter: {section: {eq: "categoryA"}}}
  ) {
    distinct(field: frontmatter___category)
    edges {
      node {
        id
        frontmatter {
          category
          path
          title
        }
      }
    }
   }

This is my frontmatter, the order is for sorting the md file in the navbar:

---
title: item 1
path: /section1/categoryA/item1
category: categoryA
section: section1
order: 1
---

My folder structure is like this:

|---contents
|   |---section1
|   |   |---categoryA
|   |   |   |---item1.md
|   |   |---categoryB
|   |   |   |---item2.md
|   |   |---categoryC
|   |   |   |---item3.md
|   |   |---categoryD
|   |   |   |---item4.md


Solution 1:[1]

By default the sort GraphQL option sorts alphabetically. In your case, if you want the default order just remove the following line:

  sort: {fields: frontmatter___order, order: ASC}

Leaving your query as:

categoryA: allMdx(
  filter: {frontmatter: {section: {eq: "categoryA"}}}
  ) {
    distinct(field: frontmatter___category)
    edges {
      node {
        id
        frontmatter {
          category
          path
          title
        }
      }
    }
   }

This should return the categories in the fetched order.

Another option is using the JavaScript sort() method before printing the categories somewhere. Something like:

let sortedData = props.data.categoryA.edges.node.sort((a, b) => a.frontmatter.order - b.frontmatter.order);

Applying your code. The idea relies on not using GraphQL sorting but JavaScript's.

let sortedData= data[section]['distinct'].sort((a, b) => a.frontmatter.order - b.frontmatter.order));

Then just loop through your sortedData in the same way.:

  {sortedData[section]['distinct'].map((category) =>(
    <SubMenu 
      key={category} 
      title={category.replace('-', ' ')}
      style={{
        fontWeight: 700,
        maxWidth: 250,
      }}
    >
      {checkCategory(category)} //get the MD files that belongs to this category
    </SubMenu>
  ))}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1