Мутация aws cdk nextjs graphql не может возвращать значение null для ненулевого типа после добавления в новое поле схемы

Я попытался изменить схему, чтобы добавить строку строки ингредиентов. Из этого кода Я в значительной степени слежу за этим https://github.com/dabit3/next.js-cdk-amplify-workshop вы можете заглянуть в папки backend и frontend, чтобы увидеть весь код

Я построил и развернул с помощью cdk

Моя ошибка внизу

Любая помощь будет отличной

Вот соответствующие части схемы в бэкэнде

# graphql/schema.graphql
type Post @aws_api_key @aws_cognito_user_pools {
  id: ID!
  title: String!
  content: String!
  ingredients: String!
  owner: String!
}

input PostInput {
  id: ID
  title: String!
  ingredients: String!
  content: String!
}

input UpdatePostInput {
  id: ID!
  title: String
  content: String
  ingredients: String
}

Вот мой graphql.js в моем внешнем коде

export const getPostById = /* GraphQL */ `
  query getPostById($postId: ID!) {
    getPostById(postId: $postId) {
      id
      title
      content
      ingredients
      owner
    }
  }
`;

export const listPosts = /* GraphQL */ `
  query ListPosts {
    listPosts {
      id
      title
      content
      ingredients
      owner
    }
  }
`;

export const postsByUsername = /* GraphQL */ `
  query PostsByUsername {
    postsByUsername {
      id
      title
      content
      ingredients
      owner
    }
  }
`;

export const createPost = /* GraphQL */ `
  mutation CreatePost($post: PostInput!) {
    createPost(post: $post) {
      id
      title
      content
      ingredients
      owner
    }
  }
`;

Затем я попробовал следующее в create-post.js в моем интерфейсе.


// pages/create-post.js
import { withAuthenticator } from "@aws-amplify/ui-react";
import { useState } from "react";
import { API } from "aws-amplify";
import { v4 as uuid } from "uuid";
import { useRouter } from "next/router";
import SimpleMDE from "react-simplemde-editor";
import "easymde/dist/easymde.min.css";
import { createPost } from "../graphql";

const initialState = { title: "", content: "", ingredients: "" };

function CreatePost() {
  const [post, setPost] = useState(initialState);
  const { title, content, ingredients } = post;
  const router = useRouter();
  function onChange(e) {
    setPost(() => ({ ...post, [e.target.name]: e.target.value }));
  }
  async function createNewPost() {
    if (!title || !content || !ingredients) return;
    const id = uuid();
    post.id = id;

    await API.graphql({
      query: createPost,
      variables: { post },
      authMode: "AMAZON_COGNITO_USER_POOLS",
    });
    router.push(`/posts/${id}`);
  }
  return (
    <div style = {containerStyle}>
      <h2>Create new Post</h2>
      <input
        onChange = {onChange}
        name = "title"
        placeholder = "Title"
        value = {post.title}
        style = {inputStyle}
      />
      <input
        onChange = {onChange}
        name = "ingredients"
        placeholder = "Ingredients"
        value = {post.ingredients}
        style = {inputStyle}
      />
      <SimpleMDE
        value = {post.content}
        onChange = {(value) => setPost({ ...post, content: value })}
      />
      <button style = {buttonStyle} onClick = {createNewPost}>
        Create Post
      </button>
    </div>
  );
}

const inputStyle = {
  marginBottom: 10,
  height: 35,
  width: 300,
  padding: 8,
  fontSize: 16,
};
const containerStyle = { padding: "0px 40px" };
const buttonStyle = {
  width: 300,
  backgroundColor: "white",
  border: "1px solid",
  height: 35,
  marginBottom: 20,
  cursor: "pointer",
};
export default withAuthenticator(CreatePost);

Затем я получаю следующее сообщение при попытке создать сообщение


{
  type: 'Object',
  stack: null,
  data: { listPosts: [ [Object], null, [Object], null ] },
  errors: [
    {
      path: [Array],
      locations: null,
      message: "Cannot return null for non-nullable type: 'String' within parent 'Post' (/listPosts[1]/ingredients)"
    },
    {
      path: [Array],
      locations: null,
      message: "Cannot return null for non-nullable type: 'String' within parent 'Post' (/listPosts[3]/ingredients)"
    }
  ]
}

Лямбда-fns/listPosts.ts

// lambda-fns/listPosts.ts
const AWS = require('aws-sdk')
const docClient = new AWS.DynamoDB.DocumentClient()

async function listPosts() {
    const params = {
        TableName: process.env.POST_TABLE,
    }
    try {
        const data = await docClient.scan(params).promise()
        return data.Items
    } catch (err) {
        console.info('DynamoDB error: ', err)
        return null
    }
}

export default listPosts

Мне не хватало добавления ингредиентов в файл Post.ts в моем бэкэнде.

// lambda-fns/Post.ts
type Post = {
    id: string,
    title: string,
    content: string,
    ingredients: string,
    owner: string
}

export default Post
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Раскрытие чувствительных данных
Раскрытие чувствительных данных
Все внешние компоненты, рассмотренные здесь до сих пор, взаимодействуют с клиентской стороной. Однако, если они подвергаются атаке, они не...
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Руководство ChatGPT по продаже мини JS-файлов
Руководство ChatGPT по продаже мини JS-файлов
JS-файл - это файл, содержащий код JavaScript. JavaScript - это язык программирования, который в основном используется для добавления интерактивности...
0
0
202
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Похоже, что в вашем вопросе отсутствуют некоторые детали отладки. Например, ваше сообщение об ошибке отображает результаты запроса listPosts, но вы нигде не показываете, что это вызывается. Кроме того, этот запрос, по-видимому, что-то возвращает, поэтому было бы неплохо увидеть записи базы данных, поддерживающие его.

Если бы мне пришлось угадывать, у вас есть записи в таблице Dynamo с отсутствующими полями ingredients, поэтому вы видите ошибку: запрос пытается маршалировать отсутствующие/пустые поля к возвращаемому типу String!, который по определению не является обнуляемый.

Кроме того, я не уверен, что вам следует устанавливать id непосредственно в объекте состояния post. Лучше скопировать объект и установить свойство для копии, особенно если вы просто используете его как параметр.

Другие вопросы по теме