0

I've created a basic Gatsby site with the default starter. I'm now trying to add some custom data (the people array) to gatsby-config.json like so:

module.exports = {
  siteMetadata: {
    title: `Gatsby Default Starter`,
    description: `XXX`,
    author: `@gatsbyjs`,
    people : [
      { id : 1234, name : "Bill Smith", sales : 143, birthdate : "2233-03-22" },
      { id : 5678, name : "Roger Miller", sales : 281, birthdate : "2230-01-06" }
    ]
  },
  plugins: [
    `gatsby-plugin-react-helmet`,
    { resolve: `gatsby-source-filesystem`,
      options: { name: `images`, path: `${__dirname}/src/images`, }
    },
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    { resolve: `gatsby-plugin-manifest`,
      options: {
        name: `gatsby-starter-default`, short_name: `starter`, start_url: `/`,
        background_color: `#663399`, theme_color: `#663399`, display: `minimal-ui`,
        icon: `src/images/gatsby-icon.png`
      }
    }
  ]
}

Then, in GraphiQL, what I'm trying to do is a query to get a list of people, but limit it to just those with sales above 200, that's my end goal. So first, I did a basic test:

{
  site {
    siteMetadata {
      people {
        name
      }
    }
  }
}

That works, I get all people back. Then, I tried:

{
  site {
    siteMetadata {
      people(sales: { gt: 200 }) {
        name
      }
    }
  }
}

That gets me an error "Unknown argument sales on field people of type SiteSiteMetadata". That kinda seems to be telling me that Sift underneath Gatsby doesn't have any notion of my custom fields in its schema, which would kind of make sense to me. So, as a test, I try this:

{
  site {
    siteMetadata(author: { eq: "none" }) {
      author
      title
    }
  }
}

My expectation is the query runs successfully but returns an empty result set since the author element's value isn't "none". But instead, I get the same basic error but now telling me "Unknown argument author on field siteMetadata of type Site" and now I'm confused because it seems like it should know about THOSE fields even if it doesn't know about arbitrary ones I add. Then again, maybe that query won't ever work because there's only a single siteMetaData object versus trying to query an array. I'm not sure.

So then I do some research and I see some reference to 'filter', so I try this now:

{
  site {
    siteMetadata(filter: { eq: "none" }) {
      author
      title
    }
  }
}

That gets me "Unknown argument filter on field siteMetadata of type Site."

And now I'm kind of out of ideas.

I did find one post that seemed to possibly imply that you can't query custom data elements like this at all, but some replies seem to imply you, in fact, can (and clearly that first test worked, so the data is found, I just can't get the filtering to work). Maybe I'm using the wrong syntax, but if so then I can't seem to find what the correct syntax looks like (and what's worse is that in the Gatsby docs, the ONE example that MIGHT provide me an answer is error'ing out in the playground and I can't see the code).

It seems like such a simple thing, but I'm at a loss. Any help would be greatly appreciated. Thanks!


EDIT: After I wrote this, I tried putting the data in a separate file that get loaded with the gatsby-transformer-json plugin and tried to query that. The data gets loaded, but I still can't filter the query. I can do:

{
  testData {
    people {
      name
      sales
    }
  }
}

...and that works, returns my data fine. But if I try:

{
  testData {
    people(sales:{gt:200}) {
      name
      sales
    }
  }
}

...or...

{
  testData {
    people(filter:{sales:{gt:200}}) {
      name
      sales
    }
  }
}

...I get the same types of errors. So, I think that at least proves this isn't an issue of querying it from siteMetaData specifically, but I still don't know how to make it do what I want.

For anyone who wants to reproduce this, just add the file data.json in the root of the project with this content:

{
  "people" : [
    { "id" : 1234, "name" : "Bill Smith", "sales" : 143, "birthdate" : "2233-03-22" },
    { "id" : 5678, "name" : "Roger Miller", "sales" : 281, "birthdate" : "2230-01-06" }
  ]
}

Then, add this to the plugins array in gatsby-config.json:

{
  resolve: `gatsby-transformer-json`,
  options: { typeName: `testData` }
},
{
  resolve: `gatsby-source-filesystem`,
  options: { name: `data`, path: `${__dirname}/data.json` }
}

No other changes from the initially-generated project are needed. Then, just hop into GraphiQL and try to execute the queries above.

Or, to make things easier, I've created a codesandbox instance that demonstrates this:

https://codesandbox.io/s/gatsby-graphql-querying-json-issue-47km4


EDIT2: I had the thought that maybe this is an issue with GraphiQL itself. So, I created a simple component:

import React from "react"
import { useStaticQuery, graphql } from "gatsby"

const Test = () => {

const testData = useStaticQuery(graphql`
  query TestDateQuery {
    testData(filter: {sales: {gte:200}}) {
      people {
        name
      }
    }
  }
`)
console.log("testData", testData);

  return (
    <div />
  )
}

export default Test

I then dropped that into my main Layout component. I get the same sort of error (about filter being an unknown argument) rather than seeing my data. If I remove the filter, I DO see ALL the data. So, again, I can't figure out why just filter isn't working, but that's what I've narrowed it down to.

Frank W. Zammetti
  • 1,231
  • 1
  • 11
  • 19
  • try to place filter on 1st/top element - no matter how depth is your filtered field – xadm Apr 30 '20 at 22:35
  • https://github.com/gatsbyjs/gatsby/issues/3401#issuecomment-448036936 – xadm Apr 30 '20 at 22:43
  • Thanks for the suggestion, but it didn't work for me. I tried it at every level, and I tried it with and without the filter keyword, none of it worked (and GraphiQL is still complaining that either sales is unknown, or filter is unknown, depending on which syntax I attempt). I took a look at that linked post and it seems like it's maybe related, but not an exact match. Worth noting I found this (https://dev.to/emmabostian/reading-data-from-a-json-file-with-gatsby--graphql-58a2), and there's a comment asking if the author tried filtering because it's not working for the poster. Same basic idea. – Frank W. Zammetti Apr 30 '20 at 23:52
  • aaaaa. siteMetaData ... is not filterable.... you can do it on page component level (or `gatsby-node.js` - after fetching data, before createPage).... json should be filterable ... ... but by `allPostsJson` like https://github.com/gatsbyjs/gatsby/blob/master/examples/gatsbygram/gatsby-node.js is limitable - explore playground .... try to prepare working [example] on codesandbox – xadm May 01 '20 at 01:14
  • filtering is not a part of graphql - it depends on implementation/env, works if supported – xadm May 01 '20 at 17:10
  • @xadm Thanks again, but I'm still stuck. I'm trying to query from a separate JSON file now (details in the edit), but hitting the same issue. I think the details above already ARE the minimal reproducible example (with the additional info I added to the first edit). Thanks for the codesanbox hint, I actually had never used that before, but I got the example up in it (see edit for URL). – Frank W. Zammetti May 01 '20 at 17:37
  • @xadm I'm not sure what you mean... filtering is in the GraphQL spec. Did you mean the exact syntax could be different? Because that I believe is true. But, according to the Gatsby docs (https://www.gatsbyjs.org/docs/graphql-reference/) it IS supported. – Frank W. Zammetti May 01 '20 at 17:39
  • no, it is not a part of graphql spec. – xadm May 01 '20 at 17:42
  • @xadm You're right, I got filtering and arguments (which often do effectively filter) confused. My bad. – Frank W. Zammetti May 01 '20 at 17:46
  • you can only filter on properties used in query – xadm May 07 '20 at 15:31
  • @xadm It doesn't appear to matter. Notice the the last query I tried above filtering on sales includes sales in the query. – Frank W. Zammetti May 07 '20 at 22:15
  • hmm... it looks like bug with `elemMatch` filtering ... `/___graphql?query=query MyQuery {%0A%20 allTestData(filter%3A {people%3A {elemMatch%3A {sales%3A {lt%3A 240}}}}) {%0A%20%20%20 edges {%0A%20%20%20%20%20 node {%0A%20%20%20%20%20%20%20 people {%0A%20%20%20%20%20%20%20%20%20 sales%0A%20%20%20%20%20%20%20%20%20 name%0A%20%20%20%20%20%20%20%20%20 id%0A%20%20%20%20%20%20%20 }%0A%20%20%20%20%20 }%0A%20%20%20 }%0A%20 }%0A}%0A&operationName=MyQuery` - condition is true if all elements matches – xadm May 08 '20 at 00:20
  • https://github.com/gatsbyjs/gatsby/issues/10990 - this can be usable – xadm May 08 '20 at 01:13

0 Answers0