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

How to query all posts by an author when you have multiple authors per post #7251

Closed
gurtjun opened this issue Aug 11, 2018 · 15 comments

Comments

Projects
None yet
7 participants
@gurtjun
Copy link
Member

commented Aug 11, 2018

Summary

I'm working on a blog where one blogpost can have multiple authors. I got this working with mappings between my nodes. I can query for a markdown file and get all the linked authors.

Now I'm working on a page for each author that displays all the posts he/she contributed to. How can this be done? Below you can find the query I'm currently using, but that one's not working (author.js).

I setup an example in this repo.

Relevant information

File contents

gatsby-config.js:

module.exports = {
  ...
  mapping: {
    "MarkdownRemark.frontmatter.authors": `AuthorYaml`,
  },
  ...
}

gatsby-node.js:

const path = require(`path`)
const { createFilePath } = require(`gatsby-source-filesystem`)

exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions
  if (node.internal.type === `AuthorYaml`) {
    const slug = createFilePath({ node, getNode, basePath: `data` })
    createNodeField({
      node,
      name: `slug`,
      value: slug,
    })
  }
}

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions
  return new Promise((resolve, reject) => {
    graphql(`
        allAuthorYaml {
          edges {
            node {
              id
              fields {
                slug
              }
            }
          }
        }
      }
    `).then(result => {
      result.data.allAuthorYaml.edges.forEach(({ node }) => {
        createPage({
          path: node.fields.slug,
          component: path.resolve(`./src/templates/author.js`),
          context: {
            // Data passed to context is available
            // in page queries as GraphQL variables.
            slug: node.fields.slug,
            id: node.id
          },
        })
      })
      resolve()
    })
  })
}

src/pages/blog/example-blog-post.md

---
title: "Example Blog Post"
date: "2018-08-11"
authors: [john_doe, jane_doe]
---

src/data/author.yaml

- id: john_doe
  name: John Doe
- id: jane_doe
  name: Jane Doe

src/templates/author.js

...
export const query = graphql`
  query($id: String!) {
    allMarkdownRemark(filter: { frontmatter: { authors: { in: [$id] } } } ) {
      edges {
        node {
          ...
          html
          ...
        }
      }
    }
  }
`
@cezarneaga

This comment has been minimized.

Copy link
Contributor

commented Aug 12, 2018

it would help if you share your repo. so that i could see details and test stuff :)
did you try

export const query = graphql`
  query($id: String!) {
    -allMarkdownRemark(filter: { frontmatter: { authors: { in: [$id] } } } ) {
    +allMarkdownRemark(filter: { frontmatter: { authors: { eq: $id } } } ) {
      edges {
        node {
          ...
          html
          ...
        }
      }
    }
  }
`
@gurtjun

This comment has been minimized.

Copy link
Member Author

commented Aug 12, 2018

Hi @cezarneaga, thanks for your response!

I setup an example in this repo. The build is currently failing because the query in author.js does not return any blog posts.
Changing the in: [$id] to eq: $id does not work for me. 😞

@gurtjun gurtjun changed the title How to get all posts by an author when you have multiple authors per post How to query all posts by an author when you have multiple authors per post Aug 12, 2018

@cezarneaga

This comment has been minimized.

Copy link
Contributor

commented Aug 12, 2018

hmm, i think there might be an issue with implementation of elemMatch and frontmatter driven data.

the query should be of the shape:

{
  allMarkdownRemark(filter:{ frontmatter:{authors: {elemMatch: { id: {eq:"jane_doe"}}}}){
...
}

because authors is of {id, name} shape not string
but this isnt the case. i think it could be a bug in how data is normalized.

i would ask for guidance from @KyleAMathews on this.
sorry i can't help more. similar normalization of data coming from an api creates expected results.

best,
C

@pieh

This comment has been minimized.

Copy link
Contributor

commented Aug 12, 2018

Please create minimal reproduction repo - I was implementing elemMatch, so if it doesn't work, you should ping me ;)

---edit
Oh sorry, I've missed example in description - I'll take a look

@gurtjun

This comment has been minimized.

Copy link
Member Author

commented Aug 13, 2018

Hi @pieh, thanks for taking a look. Please let me know if you need any help.

@sasivarnan

This comment has been minimized.

Copy link
Contributor

commented Aug 23, 2018

I am trying to do the exact same mapping on my project and struck while creating a query for listing posts created by a particular author.

I guess #7385 might be related to this and tackled together.

@gurtjun

This comment has been minimized.

Copy link
Member Author

commented Aug 23, 2018

Maybe @pieh already had some time to take a look?

@pieh

This comment has been minimized.

Copy link
Contributor

commented Oct 14, 2018

Problem here is we don't create proper filter schema for mapped fields - we need to add support for that

@pieh

This comment has been minimized.

Copy link
Contributor

commented Oct 14, 2018

All right - here's is WIP working branch that enables filtering by mapped fields master...pieh:mapping-filter-schema - this need to be cleaned up and tests definitely need to be added (and maybe more tests need to be updated)

screen shot 2018-10-14 at 23 37 37

@craftybones

This comment has been minimized.

Copy link

commented Nov 14, 2018

Until the branch is accepted and merged, do we simply filter using Array.filter on the data in JS?

@gatsbot gatsbot bot added the stale? label Feb 1, 2019

@gatsbot

This comment has been minimized.

Copy link

commented Feb 1, 2019

Hiya!

This issue has gone quiet. Spooky quiet. 👻

We get a lot of issues, so we currently close issues after 30 days of inactivity. It’s been at least 20 days since the last update here.

If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!

Thanks for being a part of the Gatsby community! 💪💜

@godmuahaha

This comment has been minimized.

Copy link

commented Feb 11, 2019

@pieh Not sure it's the same issue, but I also have problems with elemMatch:
Gatsby doesn't show errors on this query, but resulting fields are not filtered:
image

@pieh

This comment has been minimized.

Copy link
Contributor

commented Feb 12, 2019

@godmuahaha so this actually works correctly - but probably doesn't do what you want it to do

Filter only filter outs top level nodes - so it tries to find personalJson node, that contains item with level 2. And returned node satisfy that condition. But it doesn't filter items field. What I'd assume you want is described in this feature request - #10990

@godmuahaha

This comment has been minimized.

Copy link

commented Feb 12, 2019

@pieh, got it! Thanks for explanation, that feature would be very useful, I have an array of ~300 items and need only one of them

@gatsbot

This comment has been minimized.

Copy link

commented Feb 23, 2019

Hey again!

It’s been 30 days since anything happened on this issue, so our friendly neighborhood robot (that’s me!) is going to close it.

Please keep in mind that I’m only a robot, so if I’ve closed this issue in error, I’m HUMAN_EMOTION_SORRY. Please feel free to reopen this issue or create a new one if you need anything else.

Thanks again for being part of the Gatsby community!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.