birkir / gatsby-source-prismic-graphql

Gatsby source plugin for Prismic GraphQL
MIT License
137 stars 75 forks source link

query returns differently in development vs production #185

Open Funkh0user opened 4 years ago

Funkh0user commented 4 years ago

I'm starting to lose my patience fighting with gatsby / prismic and its graphql plugin. this was supposed to be a simple alternative to other solutions and its becoming anything other than that.

After losing half a day just to find out that usestaticquery doesn't work with this plugin, i'm at another impasse.

currently, I'm trying to understand why i'm getting different results from the same query between development and production.

in my development enviornment, i can use this query:

  query AffiliateQuery($uid: String) {
    prismic {
      allAffiliates(uid: $uid) {
        edges {
          node {
            _meta {
              id
              type
              uid
            }
            about
            affiliate_name
            author_name
            image_1
            image_2
            map
          }
        }
      }
      _allDocuments {
        edges {
          node {
            ... on PRISMIC_Affiliate {
              affiliate_name
              map
              _meta {
                uid
                type
                id
              }
            }
          }
        }
      }
    }
  }

without problems. works in graphiQL as well as my application.

however when I try to build this in production, I get errors telling me that the edges array of the all affiliates object is undefined. When i log that data in the console, sure enough, undefined.

when I check the graphiql interface provided through prismic (repository/graphql) the query doesn't not work, and gives me this error:

{
  "message": "Query does not pass validation. Violations:\n\nCannot query field 'prismic' on type 'Query'. (line 2, column 5):\n    prismic {\n    ^\n\nUnknown type 'PRISMIC_Affiliate'. Did you mean 'Affiliate', 'SortAffiliatey' or 'WhereAffiliate'? (line 23, column 20):\n            ... on PRISMIC_Affiliate {\n                   ^"
}

anyone have any clue whats happening cause I don't.

arnaudlewis commented 4 years ago

Hi @Funkh0user , we’ll investigate your issue but you should know that gatsby generates it’s own graphql API and so it will stitch all the schema from different input like Prismic. Meaning that it will namespace the data for Prismic and that’s why you need to specify ‘Prismic’ in your query. It’s also why the query is not identical between Prismic graphql API and the gatsby generated one. So the only place where you can test your request is on the gatsby graphiql. For your issue we’ll investigate to understand what’s going on

madeleineostoja commented 4 years ago

I've also run into this and heaps of other edge cases between preview vs build time data models with this source. For now I've told clients that previews don't work with Prismic unfortunately

Funkh0user commented 4 years ago

I've been at it all day, refactoring components, trying queries in different places, page queries and static queries, no matter what I do I keep running into the same problem.

the data from my graphql query is available in development. and I can log it when in production, but the moment I try to use it inside of my component by binding it to a variable or rendering it inside some jsx, its undefined and my build fails.

Its the exact same behavior as when I was trying useStaticQuery, i'm starting to think that ALL static queries are broken with this plugin, not just the hook.

i can log the contents of the edges array produced from the following query while in production, but if I try to access any of the data inside the edges array by calling .node, my build fails telling me that data data is undefined, even though I can see it clearly in the logs.

  query AffiliateQuery($uid: String) {
    prismic {
      allAffiliates(uid: $uid) {
        edges {
          node {
            _meta {
              id
              type
              uid
            }
            about
            affiliate_name
            author_name
            image_1
            image_2
            map
          }
        }
      }
    }
  }

I've lost so much time to struggling with the gatsby-prismic-graphql plugin it makes me want to walk away from the whole tech stack. I could have done this project three times over with other technologies that this stuff is all supposed to be the easier faster solution to.

here is the repo the project can be found at.

clone, npm install, npm start. localhost:8000. now your in development.

observe in the browser console, there is a log statement from src/components/affiliate.js that yields an object. In development I can unpack that object and use the data.

in production, its all undefined.

someone convince me not to start from scratch with a different cms or without gatsby / graphql.

MarcMcIntosh commented 4 years ago

Hi @Funkh0user

Try this

import React from "react"
import MainLayout from "../../layouts/MainLayout"
import { useStaticQuery, graphql } from "gatsby"
import { RichText } from "prismic-reactjs"

const Affiliate = () => {
  console.log("Affiliate layout");
  const data = useStaticQuery(graphql`
  query AffiliateQuery($uid: String, $lang: String) {
    prismic {
      allAffiliates(uid: $uid, lang: $lang) {
        edges {
          node {
            _meta {
              id
              type
              uid
            }
            about
            affiliate_name
            author_name
            image_1
            image_2
            map
          }
        }
      }
    }
  }
`)

  const capitalize = string => {
    return string
      .split(" ")
      .map(element => {
        return element.charAt(0).toUpperCase() + element.slice(1)
      })
      .join(" ")
  }

  console.log(
    "allAffiliates query data:",
    //this line logs in development and production
    data.prismic.allAffiliates.edges[0]
    //this line only logs in development, in production, it returns undefined and crashes my build
    // data.prismic.allAffiliates.edges[0].node
  )

  const doc = data.prismic.allAffiliates.edges.slice(0, 1).pop()
  if (!doc) return null
    // let affiliate = data.prismic.allAffiliates.edges[0].node

  return (
    <MainLayout prismicData={data}>
      {/* <h1>{RichText.render(capitalize(affiliate._meta.uid.replace("-", " ")))}</h1>
      <span>
        <img
          style={{ width: "200px", padding: "5px", float: "left" }}
          src={affiliate.image_1.url}
        ></img>
        {RichText.render(affiliate.about)}
      </span> */}
    </MainLayout>
  )
}

export default Affiliate
Funkh0user commented 4 years ago

thanks for your response.

Screen Shot 2020-04-22 at 2 32 24 AM

also now my dev build is malfunctioning. when I click on an affiliate link, they all have the same content, instead of content specific to each afiliate (as in the prismic repository)

MarcMcIntosh commented 4 years ago

Hi @Funkh0user Seems to work fine, is this the repo you are using? githum.com/Funkh0user/Global-Paradise-Studios It seems to work. try running npm run clean

Funkh0user commented 4 years ago

navigate to one of the affiliate links then look in the console. try navigating again to any of the other affiliate links. you'll see that its not working correctly.

it does "seem" to work fine, in development. it breaks in production.

Screen Shot 2020-04-22 at 3 23 41 AM

your efforts are sincerely, and enormously appreciated.

pvpg commented 4 years ago

Could you try and add a validation before saving the response data in a variable, clean the cache and run the build again? A validation is always needed: if (!theresult) return null

import { graphql } from "gatsby"

export const query = graphql`
  query AffiliateQuery($uid: String) {
    prismic {
      allAffiliates(uid: $uid) {
        edges {
          node {
            _meta {
              id
              type
              uid
            }
            about
            affiliate_name
            author_name
            image_1
            image_2
            map
          }
        }
      }
    }
  }
`

const Affiliate = props => {
   const prismicContent = data.prismic.allAffiliates.edges[0]
   if (!prismicContent) return null
   const document = prismicContent.node

  console.log(document)
  return (
    <>
        Test
    </>
  )
}

export default Affiliate
Funkh0user commented 4 years ago

both of the last 2 iterations of this component and the current one have the check before initiating a variable with the queried values. could you tell me what is different about this code snippet you'd like me to try? it looks identical to the solution @MarcMcIntosh offered but without the lang field in the query.....

I'll try it anyway, but I can't push any more builds to my host (zeit) for another 2 hrs (Gotta love these "only in production" bugs going on somewheres deep inside another persons abstraction)

thanks for the help.

Funkh0user commented 4 years ago

@PaulinaVPG you nailed it! could you explain what was going wrong for me? I'd like to learn something from this about the inner workings of this plugin / graphql / gatsby

pvpg commented 4 years ago

I'm glad it worked!

This issue occurs when having the Preview feature activated on your project. Sometimes it makes the project break on build. Adding this validations will avoid getting the error.