Answered

Gatsby - How to find Parent Node of Current Node?

How do I find the parent node of the current node in a Gatsby project? I am trying to make a breadcrumb bar module similar to the one at the top of this page: https://help.agilitycms.com/hc/en-us/articles/360002996392

In the .Net version, I could simply call SiteMap.CurrentNode.ParentNode and then repeatedly call for the next ParentNode until there were none left. But how do I do accomplish the same thing in Gatsby?

1

Comments

4 comments
  • Official comment

    There is a nested sitemap object that you can access via GraphQL.

    See the example here: https://github.com/agility/agility-website-gatsby/blob/master/src/components/GlobalHeader.js=

    The graphQL is like this:

    agilitynestedsitemap {
      internal {
        content
      }
    }
     
    It's actually just a JSON object itself, so you'll need to parse it, but it has the entire nested sitemap in there.
     
    const nestedSitemapJSON = queryData.agilitynestedsitemap.internal.content;
    const nestSitemap = JSON.parse(nestedSitemapJSON).nodes;

     

    Comment actions Permalink
  • I had actually found that code earlier and was using it! Just could not figure out how to programmatically get the target node and all of its parents.

    However, I did some more google searching and found a StackOverflow answer that had an iterative function for traversing a tree to find a target node. I adapted that function to use with the `agilitynestedsitemap` data structure and also modified it to add parents.

    For anyone else who may need it:

    const Search = (tree, value, key = "id", reverse = false) => {
    const stack = tree

    while (stack.length) {
    const node = stack[reverse ? "pop" : "shift"]()

    if (node[key] === value) {
    return node
    }

    if (node.children) {
    node.children.forEach(child => {
    child.parent = node
    })

    stack.push(...node.children)
    }
    }

    return null
    }

    export default Search



    And you use it in a component like this:

    import React from "react"
    import { graphql, StaticQuery } from "gatsby"

    import search from "../../utils/tree/search"

    const breadcrubBarQuery = graphql`
    query BreadcrubBarQuery {
    agilitynestedsitemap {
    internal {
    content
    }
    }
    }
    `

    const BreadcrumbBarComponent = (props) => {
    return (
    <StaticQuery
    query={breadcrubBarQuery}
    render={data => {
    const siteMap = JSON.parse(data.agilitynestedsitemap.internal.content)
    const nodeWithParents = search(siteMap.nodes, props.page.pageID, "pageID")

    return (
    <h6>Breadcrumb Bar</h6>
    )
    }}
    />
    )
    }

    export default BreadcrumbBarComponent

     

    To go through the whole chain of parents, just iterate through the `parent` property until you reach the node without one.

    0
    Comment actions Permalink
  • Nice work! Thanks for sharing John 👏

    0
    Comment actions Permalink
  • That's wicked!

    0
    Comment actions Permalink

Please sign in to leave a comment.

Didn't find what you were looking for?

New post