-1

I'm able to run my code in dev just fine and works as expected. Not sure what I'm doing wrong. Am I unable to create nodes and then build pages from them in gatsby-node.js? Is there a better way of doing this in gatsby that I'm not aware of?

The problem is when I try to build I receive error.

"gatsby-node.js" threw an error while running the sourceNodes lifecycle:

Request failed with status code 400

Here is my code:

   exports.sourceNodes = async ({
    actions,
    createNodeId,
    createContentDigest,
}) => {
    const { createNode } = actions
    const auth_token = Buffer.from(
        `${client_id}:${client_secret}`,
        'utf-8'
    ).toString('base64')

    const token_url = 'https://accounts.spotify.com/api/token'
    const data = qs.stringify({ grant_type: 'client_credentials' })

    const response = await axios.post(token_url, data, {
        headers: {
            Authorization: `Basic ${auth_token}`,
            'Content-Type': 'application/x-www-form-urlencoded',
        },
    })

    const access_token = await response.data.access_token

    const spotifyData = await axios.get(
        `https://api.spotify.com/v1/artists/${artistId}/albums`,

        {
            headers: {
                Authorization: `Bearer ${access_token}`,
                'Content-type': 'application/json',
            },
            params: {
                limit: 50,
                market: 'US',
                groups: 'single,album',
            },
        }
    )

    const ALBUM_NODE_TYPE = `Album`
    await spotifyData.data.items.forEach(album =>
        createNode({
            ...album,
            id: createNodeId(`${ALBUM_NODE_TYPE}-${album.id}`),
            parent: null,
            children: [],
            internal: {
                type: ALBUM_NODE_TYPE,
                contentDigest: createContentDigest(album),
            },
        })
    )
}

exports.createPages = async ({ graphql, actions }) => {
    const { createPage } = actions
    const results = await graphql(`
        {
            collections: allFile {
                distinct(field: sourceInstanceName)
                edges {
                    node {
                        id
                        sourceInstanceName
                        childMarkdownRemark {
                            id
                            fields {
                                slug
                            }
                            frontmatter {
                                title
                                image
                            }
                        }
                    }
                }
            }
            news: allFile(filter: { sourceInstanceName: { eq: "news" } }) {
                nodes {
                    sourceInstanceName
                    childMarkdownRemark {
                        frontmatter {
                            title
                            image
                            blurb
                            url
                        }
                        id
                        fields {
                            slug
                        }
                    }
                }
            }
            music: allAlbum(sort: { fields: release_date, order: DESC }) {
                nodes {
                    id
                    href
                    images {
                        url
                    }
                    name
                    artists {
                        name
                    }
                    release_date
                    album_type
                    external_urls {
                        spotify
                    }
                }
            }
        }
    `)

    // Music
    await results.data.music.nodes.forEach(node => {
        console.log(node)
        if (node.errors) {
            node.errors.forEach(e => console.error(e.toString()))
            return Promise.reject(node.errors)
        }
        const id = node.id
        const name = node.name.replace(/\s+/g, '_').toLowerCase()
        createPage({
            path: `music/${name}`,
            component: path.resolve(`src/templates/music/music.js`),
            // additional data can be passed via context
            context: {
                id,
                field: { ...node },
            },
        })
    })
    await results.data.news.nodes.forEach(node => {
        if (node.errors) {
            node.errors.forEach(e => console.error(e.toString()))
            return Promise.reject(node.errors)
        }
        const id = node.childMarkdownRemark.id
        createPage({
            path: `${node.sourceInstanceName}${node.childMarkdownRemark.fields.slug}`,
            component: path.resolve(
                `src/templates/${String(node.sourceInstanceName)}/${String(
                    node.sourceInstanceName
                )}.js`
            ),
            // additional data can be passed via context
            context: {
                id,
                field: { ...node.childMarkdownRemark.frontmatter },
            },
        })
    })
    //News Collection
    await results.data.collections.distinct.forEach(collection => {
        if (collection.errors) {
            collection.errors.forEach(e => console.error(e.toString()))
            return Promise.reject(collection.errors)
        } else {
            if (collection !== 'news') {
                return
            } else {
                const edges = results.data.collections.edges
                const nodes = edges.filter(
                    e => e.node.sourceInstanceName === 'news'
                )
                createPage({
                    path: `/collections/news`,
                    component: path.resolve(
                        `src/templates/news/collections/news.js`
                    ),
                    context: {
                        nodes: { ...nodes },
                    },
                })
            }
        }
    })
}
exports.onCreateNode = ({ node, actions, getNode }) => {
    const { createNodeField } = actions

    if (node.internal.type === `MarkdownRemark`) {
        const value = createFilePath({ node, getNode })
        createNodeField({
            name: `slug`,
            node,
            value,
        })
    }
}

I also tried wrapping the createPage function in sourceNodes but that didn't work either.

speedydev
  • 33
  • 1
  • 1
  • 6

1 Answers1

0

I ended up creating a source-plugin and passing in my Spotify credentials as a string in gatbsy-config.js. It's not able to read env variable at build time but it is when running dev and I'm not sure I understand why that is.

speedydev
  • 33
  • 1
  • 1
  • 6