【问题标题】:Unable to take time and dat as input and write into database implemented using Hasura GraphQL无法将时间和数据作为输入并写入使用 Hasura GraphQL 实现的数据库
【发布时间】:2021-02-16 13:20:12
【问题描述】:

我正在尝试使用 React 和 Hasura GraphQL 创建一个非常简单的 3 页日程管理应用程序。我将所有已安排的会议显示为一页,我将会议的标题、日期和参与者人数作为用户的输入,并将用户发送到下一页以输入会议的开始和结束时间。但是,当我尝试将输入的值写入数据库时​​,我收到一条错误消息:

variable startTime of type String! is used in position expecting time

variable date of type String! is used in position expecting Date

我不确定日期和时间是否是架构中的预期数据类型,我可以在编写查询时使用。我还附上了两个输入页面的代码,让您了解我现在做错了什么。

这是我的第一个输入页面:

import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import Form from 'react-bootstrap/Form'
import Button from 'react-bootstrap/Button'; 
import { Link } from "react-router-dom";
import { withRouter } from 'react-router-dom'

class NewSchedulePageFirst extends React.Component {
  constructor(props) {
    super(props);
    this.state= {
      title: "",
      date: "",
      participants: ""
    }

    this.handleChange=this.handleChange.bind(this);

  }

  handleChange(event) {
    const {name, value} = event.target
    this.setState({
        [name]: value
    })
  }

  render() {
    
      return (
        <div className="form">
          <div className="form-title">
            <h2>Enter details for new entry </h2>
          </div>
          <div className="form-fields">
            <Form> 
                <div className="form-title">
                  <Form.Control type="text" placeholder="Title" onChange={this.handleChange} value={this.state.title} name="title" />
                </div>
                <div className="form-date">
                  <Form.Control type="date" onChange={this.handleChange} value={this.state.date} name="date" />
                </div>
                <div className="form-participants">
                  <Form.Control type="number" placeholder="No. of participants" onChange={this.handleChange} value={this.state.participants} name="participants" />
                </div>
            </ Form>
          </div>
          <Link to={{
                pathname: "/NewSchedulePageTwo",
                state : {
                    title: this.state.title,
                    date: this.state.date,
                    participants: this.state.participants
                }
              }}>
            <Button variant="outline-primary"> Next </Button>
          </Link>

        </div>
      );
    }
}

export default withRouter(NewSchedulePageFirst) ;

这是我尝试将数据写入数据库的第二页:

import React, { useState } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import Form from 'react-bootstrap/Form'
import Button from 'react-bootstrap/Button'; 
import { GET_MY_SCHEDULE } from './currentscheduledisplay'
import { Link , withRouter } from "react-router-dom";
import { gql } from "@apollo/client";
import { useMutation } from "@apollo/client";



const ADD_SCHEDULE = gql `
mutation($title: String!, $date: String!, $startTime: String!, $endTime: String!, $participants: Int!) {
    insert_Schedule(objects: {title: $title, date: $date, startTime: $startTime, endTime: $endTime, participants: $participants }) {
      affected_rows
      returning {
        id
        title
        date
        startTime
        endTime
        participants
      }
    }
  }

 `;


function NewSchedulePageSecond(props) {
    // console.log(props.location.state);
    const { title, date, participants } = props.location.state;
      const [ stitle, setStitle ] = useState(title);
      const [ sdate, setSdate ] = useState(date);
      const [ sparticipants, setSparticipants ] = useState(participants);
      const [ startTime, setStartTime ] = useState('');
      const [ endTime, setEndTime ] = useState('');


  // handleChange(event) {
  //   const {name, value} = event.target
  //   this.setState({
  //       [name]: value
  //   })
  // }

  // scheduleInput(event) {
  //   const { value } = event.target;
  //   this.setState({schedule : value});
  // }

  // componentDidMount() {
    
  // }

  const resetInput = () => {
      setStitle(title);
      setSdate(date);
      setSparticipants(participants);
      setStartTime('');
      setEndTime('');
    
  }

    const updateCache = (cache, {data}) => {
      // Fetch the todos from the cache
      const existingSchedule = cache.readQuery({
        query: GET_MY_SCHEDULE
      });
      // Add the new todo to the cache
      const newSchedule = data.insert_todos.returning[0];
      cache.writeQuery({
        query: GET_MY_SCHEDULE,
        data: {schedule: [newSchedule, ...existingSchedule.schedule]}
      });
    };


    const [addSchedule] = useMutation(ADD_SCHEDULE, { update: updateCache, onCompleted: resetInput });

      return (
        <div className="form">
          <div className="form-title">
            <h2>Enter details for new entry </h2>
          </div>
          <div className="form-fields">
            <Form> 
                <div className="form-start-time">
                  <Form.Control type="time" onChange={(e) => setStartTime(e.target.value)} value={startTime} name="startTime" />
                </div>
                <div className="form-end-time">
                  <Form.Control type="time" onChange={(e) => setEndTime(e.target.value)} value={endTime} name="endTime" />
                </div>
            </ Form>
          </div>

          <Link to='/'>
            <Button variant="outline-primary" onClick={() => {addSchedule(
                                  {variables: {title: stitle, 
                                                date: sdate,
                                                participants: sparticipants,
                                                startTime: startTime,
                                                endTime: endTime
                                      }})}}> 
                              Create 
            </Button>
          </Link>

          {/* <p>
            Title: {title}
          </p>
          <p>
            Date: {date}
          </p> */}

        </div>
      );
    
}

export default withRouter(NewSchedulePageSecond);

我的关系的架构如下:

id - integer, primary key, unique, default: nextval('"Schedule_id_seq"'::regclass)
title - text, default: 'Meeting'::text
participants - integer, default: 2
startTime - time without time zone
endTime - time without time zone
date - text, default: 'No Date Entered'::text

我无法找到表示日期和时间的方法。我是第一次使用 GraphQl,所以如果你能解释为什么我也会收到这个错误,那就太好了。

编辑:我的突变如下:

mutation($title: String!, $date: String!, $startTime: String!, $endTime: String!, $participants: Int!) {
    insert_Schedule(objects: {title: $title, date: $date, startTime: $startTime, endTime: $endTime, participants: $participants }) {
      affected_rows
      returning {
        id
        title
        date
        startTime
        endTime
        participants
      }
    }
  }

【问题讨论】:

  • 'insert_Schedule' 变异 server 签名?参数类型?
  • @xadm 这些是我的表 'Schedule' 中的属性:- id - 整数、主键、唯一,默认值:nextval('"Schedule_id_seq"'::regclass) title - 文本,默认值: 'Meeting'::text 参与者 - 整数,默认:2 startTime - 不带时区的时间 endTime - 不带时区的时间 date - 文本,默认:'No Date Entered'::text
  • 我不关心 DB .... 在 graphiql/playground 中测试您的查询 ... docs explorer 再次显示类型 defs ...,这个突变 def 和参数类型的外观如何 - 自定义日期和时间标量...传递参数[格式]匹配这些标量要求
  • @xadm 这正是我正在努力解决的问题,如果您能更具体地说明我应该做什么来解决这个问题,那就太好了。我只是在学习 GraohQL,所以如果你能解释显而易见的事情,那就太好了。
  • 检查 SERVER 突变规范,您的 CLIENT 突变必须与 SERVER defs/arg 类型匹配...您可以在 graphiql/playground 文档中检查...或自定义类型 defs 和突变定义输入和返回类型,显示这个,而不是你怎么称呼它,是早知道的

标签: reactjs api graphql webhooks hasura


【解决方案1】:

您收到此错误是因为在您的 GraphQL 突变中,您将变量指定为 String! 类型,然后在需要 Date 的地方使用它。

例如,假设您有一个名为 update_event 的突变,其期望和参数 time 的类型为 Date,您的突变应如下所示:

mutation ($time: Date) {
    update_event(time: $time) {
        id
    }
}

不是

mutation ($time: String!) {
    update_event(time: $time) {
        id
    }
}

在这两种突变中,update_event 期望参数$time 时间为Date。在第一个突变中,它是一个Date 在第二个突变中,它是一个String!。第一个是正确的,第二个会失败。


在你的情况下,你有突变:

mutation($title: String!, $date: String!, $startTime: String!, $endTime: String!, $participants: Int!) {
    insert_Schedule(objects: {title: $title, date: $date, startTime: $startTime, endTime: $endTime, participants: $participants }) {
      affected_rows
      returning {
         # ...
      }
    }
  }

您将所有参数类型指定为 String!,但根据错误,endTimestartTime 需要指定为 time

mutation($title: String!, $date: String, $startTime: time, $endTime: time, $participants: Int!) {
    insert_Schedule(objects: {title: $title, date: $date, startTime: $startTime, endTime: $endTime, participants: $participants }) {
      affected_rows
      returning {
         # ...
      }
    }
  }

【讨论】:

  • 我已将我的突变添加为我的代码的一部分,但我也会明确添加它。当我尝试将变量的类型指定为时间(对于 startTime 和 endTime)和日期(对于日期)时,它会抛出一个错误,提示“未处理的拒绝(错误):架构中不存在此类类型:'时间''我是不知道为什么。
  • 是的,很抱歉我最初错过了它。过了一会儿我看到它并修改了我的答案。另外,我现在看到您指定了数据库字段类型。所以你有startTimetime without time zoneendTimetime without time zonedatetext。查看此表 hasura.io/docs/1.0/graphql/core/api-reference/… 并使用相应的 GraphQL 类型。所以对于前两个,对应的类型是Implicit(不知道为什么,从来没有使用过),对于DB text类型,对应的类型是String
  • 另外,我强烈建议先使用 Hasura 控制台中的“GraphiQL”页面测试您的突变并确保它有效。它会对您有很大帮助。您知道那在哪里吗?
  • 刚刚在我的 Hasura 中对其进行了测试,看起来如果您有一个 time without time zone 字段,则突变中预期的相应类型是 time。我更新了我的答案。它可能需要time! 是数据库字段不可为空。
  • date 字段上也会出错,因为您将String! 指定为类型,但它是一个可为空的字段,因此它必须是String。也更新了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多