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

Suggest, use standard apollo graphql react composing to enable chaning of graphql data fetching. #1893

Closed
timbrandin opened this issue Aug 23, 2017 · 5 comments

Comments

@timbrandin
Copy link

Hi again, still love this project!

Here's an idea, why not use the same composability that we see all over apollo stack documentation for react? like this:

const Page = ({ data: { title }, sizes }) => (
  <div>{title}<img srcSet={sizes}></div>
);

export default compose(
  graphql
(gql`
  query BlogPostByPath($path: String!) {
    markdownRemark(frontmatter: { path: { eq: $path } }) {
      html
      frontmatter {
        path
        title
        image
      }
    }
  }
  `, { options: ({ path }) => { variables: { path } } } ),
  graphql
(gql`
  query ResizedImage($image: String!) {
    sizes: imageSharp(id: { regex: $image }) {
      responsiveSizes(
        duotone: { highlight: "#f00e2e", shadow: "#192550" }
        toFormat: PNG
      ) {
        base64
        aspectRatio
        src
        srcSet
        sizes
        originalImg
        originalName
      }
    }
  }
  `, { options: ({ data: { markdownRemark: { frontmatter: { image } } } }) => { variables: { image: `/${image}/` } }, props: ({ data: { sizes } }) => ({ sizes }) }),
)(Page);

This would allow for chaning of request and using variables that are added to markdown frontmatter like the example above.

And this would also allow for adding queries to components, such as meny component or other global or partly global stuff that needs data to be rendered.

@KyleAMathews
Copy link
Contributor

Hmmm we provide automated/manual ways of linking data within the schema. E.g. your scenario above is already very doable in Gatsby.

Can definitely see how programmatic linking would be simpler for prototyping, etc. where you just want to quickly get something working.

@timbrandin
Copy link
Author

Aha, so one have to setup the link in the graphql schema. Is there an example or piece of code I can look at to try that out? I've seen that one can extend the schema, but only on the root level, is that what you are suggesting?

I was just thinking that if this supported the default graphql usage in react, it would be much easier to pick up and go for us that already have some experience in using apollo in react. And also this means that you could just link to their documentation instead of creating your own for this particular type of usage.

@KyleAMathews
Copy link
Contributor

Apollo is runtime where we run at build time so not really possible to do same things as them necessarily. That being said, this pattern is really interesting and could be supported i.e. we allow running code for graphql queries.

@timbrandin
Copy link
Author

timbrandin commented Sep 3, 2017

What is that other method you mentioned "automated/manual ways of linking data within the schema"?
I've tried setFieldsOnGraphQLNodeType without any luck in re-using the type for ImageSharp, and right now it feels impossible to get a hold of the image listed in the blog post.

This is basically what I want to do:

---
image: /path.jpg
---

And then use that image in the template for the blog post.

This also feels related:
#1874

@timbrandin
Copy link
Author

God dammit, it was easier to do than I though! I was just looking in the wrong place:

One just have to pass down data in the context of the page query, I'll close this because one just have to understand the createPage api.

This is how I solved it:

exports.createPages = ({ boundActionCreators, graphql }) => {
  const { createPage } = boundActionCreators;

  const racePageTemplate = path.resolve(`src/templates/race-page.js`);

  graphql(`{
    allMarkdownRemark(
      filter: { id: { regex: "/\/om\-loppet\//" } }
      sort: { order: DESC, fields: [frontmatter___date] }
      limit: 1000
    ) {
      edges {
        node {
          excerpt(pruneLength: 250)
          html
          id
          frontmatter {
            date(formatString: "MMMM DD, YYYY")
            path
            title
            image
          }
        }
      }
    }
  }`).then(result => {
    if (result.errors) {
      return Promise.reject(result.errors);
    }

    result.data.allMarkdownRemark.edges
      .forEach(({ node }) => {
        createPage({
          path: node.frontmatter.path,
          component: racePageTemplate,
          context: {
            image: node.frontmatter.image,
          } // additional data can be passed via context
        });
      });
  });
}

And in the template:

export const pageQuery = graphql`
  query RacePageByPath($path: String!, $image: String) {
    markdownRemark(frontmatter: { path: { eq: $path } }) {
      html
      frontmatter {
        date
        path
        title
        subtitle
        page_title
        description
        image
        map
      }
    }
    imageRight: imageSharp(id: { regex: $image }) {
      responsiveSizes(
        toFormat: PNG
      ) {
        base64
        aspectRatio
        src
        srcSet
        sizes
        originalImg
        originalName
      }
    }
  }
`
;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants