'sort content by tag in Gatsby with Conteful API

In Contentful, I create a content with few media pictures. The pictures have two different tags boxon and attaqueGenetique. I want to sort the slideshow by using tags I've added for each media, but I don't find the way to do that. There is an example on the website Gatsby, but is not really clear and my try failed to make it mine.

The example from Gatsby

query FilterByTagsQuery {
  allContentfulNumber(
    sort: { fields: contentful_id }
    filter: {
      metadata: {
        tags: { elemMatch: { contentful_id: { eq: "numberInteger" } } }
      }
    }
  ) {
    nodes {
      title
      integer
    }
  }
}

I've supposed I must transpose thise code to mine where allContentfulNumber become allContentfulDiaporama, and

metadata: {
        tags: { elemMatch: { contentful_id: { eq: "numberInteger" } } }
      }

become

metadata: {
        tags: { elemMatch: { contentful_id: { eq: "boxon" } } }
      }

but when I try to compile the console return 56:5 error Field "metadata" is not defined by type "ContentfulDiaporamaFilterInput" graphql/template-strings

I don't know where catch metadata from media when it's imported in content... but I'm very beginner with graphql and Contentful. If there is a solution, that's can make my day happy !!!



Solution 1:[1]

metadata in Gatsby's example is a GraphQL node valid in their data structure, if yours hasn't it simply don't use it or it will break the code since it's not a valid custom type.

The problem in your query, besides using an invalid field (metadata) is that you are using an elemMatch filter, comparingcontentful_id (number) to boxon (string), so it will never work in your scenario (it works in Gatsbys' because it's the same type). In your case, you may want to use in (for arrays) or eq (for single values). Check the available list at: https://www.gatsbyjs.com/docs/graphql-reference/#filter

As far as I understand your question, it seems that you want to split your diaporama data in two different nodes, the ones that contain boxon and the ones that contain attaqueGenetique. If so, you will need to create different nodes by aliasing them:

query FilterByTagsQuery {
  boxon: allContentfulDiaporama(
    sort: { fields: contentful_id }
    filter: {
        metadata: { tags: { in: ["boxon"]  } }
      }
  ) {
    nodes {
      #your data/fields here
    }
  }
  attaqueGenetique: allContentfulDiaporama(
    sort: { fields: contentful_id }
    filter: {
        metadata: { tags: { in: ["attaqueGenetique"]  } }
      }
  ) {
    nodes {
      #your data/fields here
    }
  }
}

Test the query in the GraphiQL playground, available at localhost:8000/___graphql where it will be much more intuitive for you to add or remove filters and see the available nodes.

The snippet above will generate two different data structures based on the tags aliased. With this: boxon: allContentfulDiaporama, you are aliasing the result of allContentfulDiaporama in boxon so in your page, you will be able to access directly props.data.boxon and props.data.attaqueGenetique respectively.

Keep in mind that the sort filtering method only works on dates or numeric values, in the case of strings, it will sort them alphabetically. So I'm assuming that your data has a contentful_id (I'm not sure how it will be helpful sorting by contentful_id).

According to this pull-request the enableTags feature was fixed in the cutting-edge release(5 days ago) so try to upgrade your plugin dependency.

It seems to be fixed in, according to this GitHub thread:

[email protected]

Or in the next release.

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