Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] Add support for arguments on GraphQL fields that return arrays #3643

Closed
geoffdavis92 opened this issue Jan 21, 2018 · 17 comments
Closed
Labels
help wanted Issue with a clear description that the community can help with.

Comments

@geoffdavis92
Copy link

Description

It would be nice to have the ability to assign arguments onto dynamically-created schemas' node fields that return arrays.

Arguments could be near-identicle to *Connection types:

  • skip
  • limit
  • sort
  • filter

Those existing arguments could be modified to support array-specific needs, like exposure of an __index-type field and array index wrapping:

characters(sort: { fields: [__index], order: ASC }, limit: 2)

New arguments could also be created to simplify filtering arrays and/or return specific indicies:

  • in: identicle to how this is used in the *Connection argument filter, except it is applied directly onto the array-returning field (e.g. characters(in: {name: {eq: "Frodo Baggins"}}))
  • index: allow retrieval of specific indices by passing them to index in an array (e.g. characters(index: [0, 1]), characters(index: [2]), characters(index: [-1]))

@KyleAMathews suggested I open an issue to add this support for passing arguments to sub-arrays on the Discord chat; the only issues that I found that pertained to this issue are #2430 and #1645.

Environment

Gatsby version: ^1.9.158
Node.js version: 8.9.1
Operating System: MacOS El Capitan 10.11.6

Steps to reproduce

I have set up a working demo project that features some sample data, some working queries, and an example of the aforementioned experimental array field arguments.

@flmuel
Copy link
Contributor

flmuel commented Jan 22, 2018

maybe related to #3190

@KyleAMathews
Copy link
Contributor

@flmuel no these are unrelated — @geoffdavis92 is asking for the ability to sort/filter on graphql lists not linked nodes.

@loremipson
Copy link
Contributor

I think I'm running into this issue right now with gatsby-transformer-json. Any array data in my json is being transformed into an InputObject and available in Graph via in: []? Anytime I include this in in my query/filter I am getting null data returned.

In my json, I have an array of objects, I would expect my query to be this, or similar:

{
    dataJson(data: { pages: { name: { eq: "index" } }) {
        data {
          pages {
            name
          }
       }
    }
}

Because of that in, graph "suggests" this query:

{
    dataJson(data: { pages: { in: { name: { eq: "index" } } }) {
        data {
          pages {
            name
          }
       }
    }
}

But anytime in is included at all, data just returns null.. I'm guessing this is related to this issue, but I'm curious if I'm just writing my query wrong.

@m-allanson
Copy link
Contributor

@pieh might have an answer for @loremipson's question above?

@m-allanson m-allanson added help wanted Issue with a clear description that the community can help with. 🏷 type: feature labels Apr 26, 2018
@pieh
Copy link
Contributor

pieh commented Apr 26, 2018

It seems gatsby doesn't actually support properly constructing input schema for array of objects (I don't think we should have that eq inside in operator). Will check if we can fix it.

@LekoArts
Copy link
Contributor

LekoArts commented Jul 2, 2018

@pieh I'd need that feature for my Prismic source to grab the tags.

I get as an output:

"tags": [
                {
                  "tag": {
                    "document": [
                      {
                        "data": {
                          "tag": "elitepvpers"
                        }
                      }
                    ]
                  }
                },
                {
                  "tag": {
                    "document": [
                      {
                        "data": {
                          "tag": "Wallpaper"
                        }
                      }
                    ]
                  }
                }
              ],

@KyleAMathews
Copy link
Contributor

@LekoArts a good start to fixing this would be to create a PR with a new test for this functionality in https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/src/schema/__tests__/infer-graphql-input-type-test.js

That test should be failing and then it'd be easy for one of us to figure out how to fix it.

@bzhr
Copy link

bzhr commented Jul 4, 2018

@KyleAMathews @LekoArts I think that the error happens when filtering on an array of objects. I think this kind of data structure is needed in order to re-create the error.

@LekoArts
Copy link
Contributor

Feature got merged in the meantime.

@geoffdavis92
Copy link
Author

Thanks all! Great to see @KyleAMathews @LekoArts

@senorgeno
Copy link

senorgeno commented Feb 28, 2019

Hey @LekoArts or @KyleAMathews I can't work out from the docs or code how this is meant to work if it has been merged. I get into a circular loop of duplicate issues.

I have this query

{
  dataJson(data: {allRestaurants: {elemMatch: {id: {eq: "132"}}}}) {
    data {
      allRestaurants {
        id
        title
      }
    }
  }
}

but it doesn't do any filtering. e.g. results

{
  "data": {
    "dataJson": {
      "data": {
        "allRestaurants": [
          {
            "id": "132",
            "title": "Jervois Steak House"
          },
          {
            "id": "682",
            "title": "Bessie"
          },
          {
            "id": "71",
            "title": "Blue Kanu"
          },
          {
            "id": "1050",
            "title": "Bazaar Interactive Marketplace"
          },
          {
            "id": "1300",
            "title": "Louis Champagne & Oyster Bar"
          },
          {
            "id": "2018",
            "title": "Takumi Japanese Restaurant & Bar"
          },
          {
            "id": "1343",
            "title": "Euro Bar & Restaurant"
          },
          {
            "id": "2360",
            "title": "Orleans Auckland"
          },
          {
            "id": "1053",
            "title": "The Grille by Eichardt's"
          },
          {
            "id": "2350",
            "title": "Orleans"
          },
          {
            "id": "2245",
            "title": "Vault 21"
          },.......

Any idea what I am doing wrong or is this not possible? My GraphQL data is being generated from gatsby-transformer-json

@senorgeno
Copy link

Never mind, i ended up building a source plugin for my use case

@AleC77
Copy link

AleC77 commented Mar 1, 2019

Never mind, i ended up building a source plugin for my use case

Can you provide a link for the source plugin? I have the same problem. Thank you

@senorgeno
Copy link

@AleC77 it is currently part of my private repository. It works for my use case but i think it would need more work for it be useful to others.

@AleC77
Copy link

AleC77 commented Mar 1, 2019

Can you send me a short piece of code of that? I am becoming crazy to find a solution. It looks it is impossible with graphql filter the content of json file for me

@senorgeno
Copy link

@AleC77 have a look at what this module does with create node - https://github.com/GraphCMS/gatsby-source-graphcms/blob/master/src/util.js and then look at this tutorial - https://www.gatsbyjs.org/docs/source-plugin-tutorial/

You basically need to take the JSON, loop over it and create a gatsby node.

forEach(data, (value, key) => {
        const type = extractTypeName(key);
        forEach(value, (obj) => {
          const { id } = obj;

          const jsonNode = JSON.stringify(obj);
          const gatsbyNode = {
            id,
            ...obj,
            parent: null,
            children: [],
            internal: {
              type: type,
              content: jsonNode,
              contentDigest: createContentDigest(obj)
            }
          };

          createNode(gatsbyNode)
        });
      });

@AleC77
Copy link

AleC77 commented Mar 4, 2019

Thank you so much for the help @senorgeno

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Issue with a clear description that the community can help with.
Projects
None yet
Development

No branches or pull requests

10 participants