prismicio / prismic-gatsby

Gatsby plugins for building websites using Prismic
https://prismic.io/docs/technologies/gatsby
Apache License 2.0
313 stars 97 forks source link

Unable to pull data from group containing content relationships #43

Closed stoutlabs closed 5 years ago

stoutlabs commented 6 years ago

I have a content type of 'Location', which holds a group of content relationships to a content type of 'Project'. (E.g. the "New York" location holds around 10 "Projects".)

  1. I have no problem fetching the correct data via GraphiQL... but it errors out when compiling with the same query.

  2. I have no trouble pulling the data when the content relationship is 1:1... things compile fine.

This is my query in gatsby-node.js.

const projectsByLocation = await graphql(`
      {
         allPrismicLocations {
            edges {
               node {
                  uid
                  data {
                     projects {
                        project {
                           document {
                              uid
                           }
                        }
                     }
                     title {
                        text
                     }
                  }
               }
            }
         }
      }
   `);

(This works perfectly in GraphiQL... but fails on compile with an error message of: "TypeError: Cannot read property 'allPrismicLocations' of undefined.)

And removing

projects {
   project {
      document { 
         uid
      }
   }
}

allows it to compile fine, but with no project data.

Is this a limitation, or am I doing something incorrectly? Sorry - my brain is mush after trying to solve this for the past 7 hours.

stoutlabs commented 6 years ago

Update: After some sleep (ha!), and a little digging in the docs /debugging... I was led to try this:

projects {
  theproject {
    __typename
    //#note: 'theproject' is the value of the api field for the relation field in the group, NOT the content type (project).
    ... on theproject {
      document {
         id
         uid
      }
    }
  }
}

Which finally pulled all the necessary related data into Gatsby! 😃

(I'm still not sure why the original query works in GraphiQL though.)

angeloashmore commented 6 years ago

Hey @stoutlabs, glad you were able to find some kind of workaround. That looks unusual, so I hope we can find why it works and why the first query doesn't.

Based on that updated query, it looks like theproject could contain multiple types of nodes.

Are you able to view the different __typename values? Maybe there's another field elsewhere in your data that uses the same name that's causing the unexpected behavior?

stoutlabs commented 6 years ago

Hey! In Prismic, I have that group field (api ID is 'theprojects') limited to only contain items of content type "project". I console logged the query output, and the typename values present are all "theproject".

Note: I had renamed the group field's api ID to "theprojects" from "projects", and the repeating relational field's api ID to "theproject" from "project", just in case there was a naming conflict. That had no effect... it worked in graphiQL, but not Gatsby. (It only worked in Gatsby after I changed it to the ... on theproject { } syntax mentioned above.)

angeloashmore commented 6 years ago

If you're able to, could you post your Prismic JSON schema for your Locations custom type?

stoutlabs commented 6 years ago

Certainly!

Here is the Locations schema:

{
  "Main" : {
     "uid" : {
       "type" : "UID",
       "config" : {
         "label" : "uid"
       }
     },
     "title" : {
       "type" : "StructuredText",
       "config" : {
         "single" : "heading2",
         "label" : "Title"
       }
     },
     "intro_image" : {
       "type" : "Image",
       "config" : {
         "constraint" : {
           "width" : 1200
         },
         "thumbnails" : [ ],
         "label" : "Intro Image"
       }
     },
     "theprojects" : {
       "type" : "Group",
       "config" : {
         "fields" : {
           "theproject" : {
             "type" : "Link",
             "config" : {
               "select" : "document",
               "customtypes" : [ "projects" ],
               "label" : "Project"
             }
           }
         },
         "label" : "Projects"
       }
     }
   }
}

and here is the projects schema:

{
  "Main" : {
    "title" : {
      "type" : "StructuredText",
      "config" : {
        "single" : "heading1, heading2, heading3, heading4, heading5, heading6",
        "label" : "Title"
      }
    },
    "uid" : {
      "type" : "UID",
      "config" : {
        "label" : "Unique ID"
      }
    },
    "pictures" : {
      "type" : "Group",
      "config" : {
        "fields" : {
          "picture" : {
            "type" : "Image",
            "config" : {
              "constraint" : {
                "width" : 1200
              },
              "thumbnails" : [ ],
              "label" : "Picture"
            }
          }
        },
        "label" : "Pictures"
      }
    }
  }
}
angeloashmore commented 6 years ago

I'm going to rubber duck a bit here.

If the Link field (theproject in this case) could contain multiple types, then __typename becomes available and ... on PrismicMyContentType {} becomes necessary.

For example, if you have a Group called my_relations, containing a Link field called relation which links to a Page and Image custom type, then you could use the following to query it:

{
  allPrismicMyContentType {
    edges {
      node {
        data {
          my_relations {
            relation {
              document {
                __typename
                ... on PrismicPage {
                  uid
                }
                ... on PrismicImage {
                  uid
                }
              }
            }
          }
        }
      }
    }
  }
}

If the relation Link field only contains a single type of content, then __typename and ... on PrismicMyContentType {} is not necessary (and will probably error).

{
  allPrismicMyContentType {
    edges {
      node {
        data {
          my_relations {
            relation {
              document {
                uid
              }
            }
          }
        }
      }
    }
  }
}

So based on this, your original query looks right.

The only way __typename could be available under theproject is if there are multiple types in the theproject array.

Could you use GraphiQL to find out what the type of theproject is? Since you're seeing __typename, the type should look something like [UNION_xxxxxx...]

stoutlabs commented 6 years ago

Maybe it's due to the repeating field being a custom type? I see in the JSON schema where Prismic puts it into an array ("customtypes"), and with non-custom repeating fields it uses a single "type" field.

(In other words, perhaps since the "type" is wrapped in an array it assumes the possibility of multiple types... even if there is only one currently in use.)

stoutlabs commented 6 years ago

Hmm... the type that is returned for "theproject" is "theproject_2".

This also solved an issue I was having inside a page in Gatsby. In the query, I swapped "theproject" out for "theproject_2" and it started working:

export const query = graphql`
   query AllInteriorsListQuery($uid: String!) {
      prismicLocations(uid: { eq: $uid }) {
         uid
         data {
           theprojects {
               theproject {
                  __typename
                  ... on theproject_2 {
                     document {
                        uid
                        data {
                           title {
                              text
                           }
                        }
                     }
                  }
               }
            }
            title {
               text
            }
            intro_image {
               localFile {
                  childImageSharp {
                     id
                     sizes(maxWidth: 800, quality: 77) {
                        ...GatsbyImageSharpSizes
                     }
                  }
               }
            }
         }
      }
   }
`;
stoutlabs commented 6 years ago

I think I'm going to chalk this issue up to something on Prismic's end... as I recreated the whole setup, and didn't have any of the same issues.

I think the weird type name of theproject_2 was due to creating a "theproject" type, deleting it, and then making another "theproject" type a couple days later. (Prismic must have added the _2 suffix on there to prevent conflicts, even though I deleted the original.)

Sorry to leave this issue open for so long with no activity! I can close it, unless you'd prefer to keep it open?

henrymyers commented 6 years ago

I'm having a very similar issue.

I have a group containing only content relationships (restricted to a single type), but in GraphiQL and Gatsby, each item is missing the document property. As was the case for @stoutlabs, 1:1 content relationships work fine.

Knowing that plans is a group of pricing_plan and recommended_plan is a single pricing_plan :

Here is the query in GraphiQL

graphiql

The fields in Prismic prismic_tab

The PricingTab fields in our redux-state.json redux_state_

And one PricingPlan from our same redux-state.json screen shot 2018-09-06 at 4 05 50 pm

Any ideas are welcome, as this is pretty much a blocking issue for us.

Thanks!

henrymyers commented 6 years ago

After further investigation, this is due to a Gatsby issue.

See PR https://github.com/gatsbyjs/gatsby/pull/7971

henrymyers commented 6 years ago

Fix merged in gatsby@2.0.0-rc.19

angeloashmore commented 6 years ago

@henrymyers Thanks for pointing that out! Everything looked right on our end, so that was confusing.

angeloashmore commented 5 years ago

Closing this as it seems to have been resolved.

jordyvanraaij commented 5 years ago

I'm using the V3 version and I'm running into the same issue. I can't get the content from a Group of documents. Anyone else experiencing this?

Screenshot 2019-09-13 at 11 57 53

angeloashmore commented 5 years ago

@jordyvanraaij The group looks fine, but querying link fields is a bit different than what you have there. Are you trying to get data from the linked document?

More detailed info here: https://github.com/angeloashmore/gatsby-source-prismic/blob/v3-beta/docs/migrating-from-v2-to-v3.md#accessing-linked-documents

jordyvanraaij commented 5 years ago

@angeloashmore I know the queries are different, but I thought you still need the document before you can do the ... on Blah query? In the following screenshot I'd expect the option to spread the content type PrismicCase but it can't find it. The document is also not available on case and if I use the suggested PrismicCasesOverviewDataCasesCase I still can't get the data. Do you have a solution or can you reproduce this?

Screenshot 2019-09-16 at 09 37 11
jordyvanraaij commented 5 years ago

@angeloashmore I know the queries are different, but I thought you still need the document before you can do the ... on Blah query? In the following screenshot I'd expect the option to spread the content type PrismicCase but it can't find it. The document is also not available on case and if I use the suggested PrismicCasesOverviewDataCasesCase I still can't get the data. Do you have a solution or can you reproduce this?

Screenshot 2019-09-16 at 09 37 11

@angeloashmore Do you have any idea? We're kind of stuck now and can't rollout the preview functionality for our website. If you need anything from me for you to test please let me know.

henrymyers commented 5 years ago

@jordyvanraaij if case is a link field pointing to another document, you should have a document property inside the link field.

prismicCasesOverview {
    data {
        cases {
            case {
                document {
                    uid
                    data {
                        meta_title
                    }
                }
            }
        }
    }
}
Hahlh commented 3 years ago

@jordyvanraaij (or maybe @angeloashmore) Did you find a fix for this at some point or realized where you went wrong?

I am currently facing the exact same issue.

After having created a single type for a page, I added two content relationship for selecting two featured articles, but I am unable to see "document" as a query option.

image

image

I double checked the schemas several times, experimented with using selection fields instead and tried to use prismicHome, but all to no avail.

I also can't access "document" if I look at dataRaw instead.

What am I missing?

I would be thankful if someone could point me in the right direction.

angeloashmore commented 3 years ago

@Hahlh Can you double check that you added your page custom type JSON schema to gatsby-config.js?

It looks like Gatsby is inferring the types, so it doesn't know that "PrismicPage" is a Prismic document.

You should be providing it to the schemas option like the following:

{
  resolve: 'gatsby-source-prismic',
  options: {
    // your other options
    schemas: {
      // your other schemas
      page: require('./src/schemas/page.json'), // Replace the path to the JSON file in your project
    }
  }
}
Hahlh commented 3 years ago

@angeloashmore , you are great!

This is the second time that not adding the schema to gatsby-config.js was the cause of an issue.

Thank you for your fast response and your help!

angeloashmore commented 3 years ago

@Hahlh Great, glad to hear it's working!

The next major version of the plugin will tell you if you're missing a schema to help others in the future. Something like the following will be printed when running gatsby develop:

 ERROR #11331  PLUGIN

Invalid plugin options for "gatsby-source-prismic":

- JSON schema for "navigation" is missing
- JSON schema for "not_found_page" is missing
- JSON schema for "settings" is missing

not finished load plugins - 0.720s
Hahlh commented 3 years ago

That would be a great addition. Thank you again for the help!