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 · 19 comments
Closed
Labels
stale? Issue that may be closed soon due to the original author not responding any more. status: confirmed Issue with steps to reproduce the bug that’s been verified by at least one reviewer. type: bug An issue or pull request relating to a bug in Gatsby

Comments

@gurtjun
Copy link
Contributor

gurtjun 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
Copy link
Contributor

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
Copy link
Contributor Author

gurtjun 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
Copy link
Contributor

cezarneaga 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
Copy link
Contributor

pieh 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
Copy link
Contributor Author

gurtjun commented Aug 13, 2018

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

@Chuloo Chuloo added type: question or discussion Issue discussing or asking a question about Gatsby status: needs more info Needs triaging and reproducible examples or more information to be resolved labels Aug 15, 2018
@sasivarnan
Copy link
Contributor

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
Copy link
Contributor Author

gurtjun commented Aug 23, 2018

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

@pieh pieh added type: bug An issue or pull request relating to a bug in Gatsby status: confirmed Issue with steps to reproduce the bug that’s been verified by at least one reviewer. and removed status: needs more info Needs triaging and reproducible examples or more information to be resolved type: question or discussion Issue discussing or asking a question about Gatsby labels Oct 14, 2018
@pieh
Copy link
Contributor

pieh 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
Copy link
Contributor

pieh 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
Copy link

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? Issue that may be closed soon due to the original author not responding any more. label Feb 1, 2019
@gatsbot
Copy link

gatsbot bot 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
Copy link

@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
Copy link
Contributor

pieh 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
Copy link

@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
Copy link

gatsbot bot 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!

@KyleAMathews
Copy link
Contributor

@freiksenet @stefanprobst is this fixable now?

@stefanprobst
Copy link
Contributor

This should be working already:

{
  allMarkdownRemark(filter: {frontmatter: {authors: {elemMatch: {id: {eq: $id}}}}}) {
    edges {
      node {
        frontmatter {
          title
          authors {
            id
            name
          }
        }
      }
    }
  }
}

Note that filtering by name should work just as well as by id:

{
  allMarkdownRemark(filter: {frontmatter: {authors: {elemMatch: {name: {eq: "Jane Doe"}}}}}) {
    edges {
      node {
        frontmatter {
          title
          authors {
            id
            name
          }
        }
      }
    }
  }
}

There are other approaches to getting posts by author as well, for example you can add a posts field directly on the AuthorJson type, or add a custom root query field postsByAuthor. Some of those approaches are documented in the schema customization guide.

@gurtjun sidenote: make sure to use .map instead of .forEach here to actually display the results

@jmolivas
Copy link

jmolivas commented May 25, 2019

Yup, I can also confirm this is working fine cc: @KyleAMathews @stefanprobst

@jonathansgardner
Copy link

jonathansgardner commented Feb 24, 2020

I am trying to do exactly this with a variable list and getting a specific entry by it's type and it is not working.

my query is:

query MyQuery {
  allMarkdownRemark(filter: {frontmatter: {sections: {elemMatch: {type: {eq: "pagePreview"}}}}}) {
    edges {
      node {
        frontmatter {
          sections {
            linkText
            page
            type
            content
            heading
          }
        }
      }
    }
  }
}

it is returning an array with all sections regardless of their type

is there a way to use createResolve to add a getByType query to the MarkdownRemarkFrontmatterSectionsFilterListInput type?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale? Issue that may be closed soon due to the original author not responding any more. status: confirmed Issue with steps to reproduce the bug that’s been verified by at least one reviewer. type: bug An issue or pull request relating to a bug in Gatsby
Projects
None yet
Development

No branches or pull requests