ошибка В вашем запросе GraphQL произошла ошибка: переменная «$slug» требуемого типа «String!» не была предоставлена

#javascript #reactjs #graphql #gatsby #netlify

#javascript #reactjs #graphql #gatsby #netlify

Вопрос:

Заголовок выше — это сообщение об ошибке, а ниже — код. Я столкнулся с этим, следуя руководству по Gatsby. Интересно, знает ли кто-нибудь, что произошло, и может дать мне некоторое представление о том, что произошло. Я мало представляю, что происходит. извините……

 import React from 'react'
import { graphql } from 'gatsby'
import Layout from '../components/layout'
import { parseImageUrl } from '@conradlin/notabase/src/utils'


export default ({ data }) => {
  const { posts: { title, tags, publish_date, html, url, slug, desc, color, cover_image } } = data

  return (
    <Layout>
      <div id = "main">
        <div>{tags amp;amp; tags.join(', ')}</div> 
        <h1>{title}</h1>
        <div dangerouslySetInnerHTML={{ __html: html }} />
      </div>
    </Layout>
  )
}

export const query = graphql`
  query($slug: String!) {
    posts(slug: { eq: $slug }) {
      html
      title
      tags
      publish_date{
        startDate(formatString: "YYYY-MMM-DD", fromNow: false)
      }
      url
      desc
      color
      cover_image
    }
  }
 

Руководство здесь для справки
https://conradlin.com/blog/posts/host-gatsbyjs-blog-with-notion-cms-and-netlify-for-free

Это должен быть код запроса

 const path = require(`path`)

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions

  const blogPost = await graphql(`
  query {
      allPosts(filter: {status: {eq: "published"}, content_type: {eq: "article"}}) {
          nodes {
            slug
            url
          }
        }
      }
    `).then(result => {
      if (result.errors) {
        Promise.reject(result.errors);
      }
      
      result.data.allPosts.nodes.forEach(({ slug, url }) => {
        createPage({
            path: `blog/posts/${url}`,
            component: path.resolve(`./src/templates/blogPost.js`),
            context: {
                // Data passed to context is available
                // in page queries as GraphQL variables.
                slug: slug,
            },
        });
    });
  });
  const newsPost = await graphql(`
  query {
      allPosts(filter: {status: {eq: "published"}, content_type: {eq: "newsletter"}}) {
          nodes {
            slug
            url
          }
        }
      }
    `).then(result => {
      if (result.errors) {
        Promise.reject(result.errors);
      }
      
      result.data.allPosts.nodes.forEach(({ slug, url }) => {
        createPage({
            path: `subscribe/posts/${url}`,
            component: path.resolve(`./src/templates/blogPost.js`),
            context: {
                // Data passed to context is available
                // in page queries as GraphQL variables.
                slug: slug,
            },
        });
    });
  });

  return Promise.all([blogPost, newsPost]);
};
 

Комментарии:

1. Вам нужно будет опубликовать код, который фактически запускает запрос, потому что это то, что выдает вашу ошибку

Ответ №1:

Если вы посмотрите на:

   result.data.allPosts.nodes.forEach(({ slug, url }) => {
    createPage({
        path: `subscribe/posts/${url}`,
        component: path.resolve(`./src/templates/blogPost.js`),
        context: {
            // Data passed to context is available
            // in page queries as GraphQL variables.
            slug: slug,
        },
    });
 

Этот фрагмент относится к gatsby-node.js , где вы создаете страницы динамически на основе запроса GraphQL для allPosts . В этом случае вы создаете каждое сообщение, которое будет иметь следующий URL-адрес:

 path: `subscribe/posts/${url}`,
 

Однако, чтобы отфильтровать данные для каждой конкретной записи, вам необходимо перейти к шаблону (установленному с component: path.resolve('./src/templates/blogPost.js') помощью ), в котором вам необходимо передать поле идентификатора, обычно the id , the slug или какое-либо другое уникальное значение. Этот поток данных выполняется из-за контекста, где вы указываете, какой параметр передается в шаблон компонента, в данном случае slug:

 context: {
    // Data passed to context is available
    // in page queries as GraphQL variables.
    slug: slug,
},
 

Таким образом, в вашем шаблоне вы можете сделать:

 export const query = graphql`
  query($slug: String!) {
    posts(slug: { eq: $slug }) {
      html
      title
      tags
      publish_date{
        startDate(formatString: "YYYY-MMM-DD", fromNow: false)
      }
      url
      desc
      color
      cover_image
    }
  }
 

Обратите ($slug: String!) внимание, что восклицательный знак ( ! ) означает, что поле не может быть обнуляемым для запроса GraphQL, или, другими словами, это обязательно. Ваш код ломается, потому что где-то в вашем запросе GraphQL (в вашем gatsby-node.js ) вы передаете пустое / null значение этому шаблону, и запрос прерывается.

Отладьте, что происходит в этом запросе, или удалите ненулевой параметр с помощью:

 query($slug: String)
 

Однако это позволит обойти нарушение кода, но проблема будет сохраняться, поскольку вы предоставляете пустое значение.

Комментарии:

1. Большое вам спасибо за то, что нашли время ответить и прояснить ситуацию. Не могли бы вы, пожалуйста, подсказать, какая часть кода в gatsby-node.js является ли null или empty? Я обновил приведенный выше код. Я попытался удалить ненулевой параметр, но ошибка осталась

2. Ваш slug , кажется, равен нулю в вашем forEach цикле. Попробуйте добавить отладчик / console.log туда, чтобы узнать, что там происходит. Попробуйте передать url параметр вместо slug, он должен быть уникальным, чтобы он работал