'GraphQL + ReactJS throws Error 400: Bad Request
I've been stuck at trying to submit my form for a couple of days now. I constantly get hit with the following error: "POST http://localhost:5000/graphql 400 (Bad Request)".
I believe the problem lies somewhere within the mutation/query itself and not the headers since the request is sent in the correct content type (application/json) as you can see in the screenshot.
My code (warning, I'm an absolute beginner) is the following:
// @flow
import React, { useState } from 'react';
import { Row, Col, Card, OverlayTrigger, Tooltip } from 'react-bootstrap';
import { FormInput } from '../../../../components';
type ChecklistsItems = {
id: number,
title: string,
completed: boolean,
};
type AttachmentsItems = {
id: number,
filename: string,
size: string,
};
type CommentsItems = {
id: number,
author: string,
text: string,
posted_on: string,
author_avatar: string,
};
type TaskProps = {
id: number,
title: string,
assigned_to: string,
assignee_avatar: string,
due_date: string,
completed: boolean,
priority: string,
stage: string,
checklists: Array<ChecklistsItems>,
description: string,
attachments: Array<AttachmentsItems>,
comments: Array<CommentsItems>,
};
const createMarkup = (text) => {
return { __html: text };
};
const Task = (task: TaskProps): React$Element<React$FragmentType> => {
const [completed, setCompleted] = useState(task.completed == true);
const [enteredTitle, setEnteredTitle] = useState('');
const [enteredPriority, setEnteredPriority] = useState('');
const [enteredDescription, setEnteredDescription] = useState('');
const [enteredDeadline, setEnteredDeadline] = useState('');
const [enteredStartTime ,setEnteredStartTime] = useState('');
const [enteredEndTime, setEnteredEndTime] = useState('');
const [enteredColor, setEnteredColor] = useState('');
/*
* mark completd on selected task
*/
const markCompleted = (e) => setCompleted(e.target.checked);
const titleChangeHandler = (event) => {
setEnteredTitle(event.target.value);
};
const priorityChangeHandler = (event) => {
setEnteredPriority(event.target.value);
};
const descriptionChangeHandler = (event) => {
setEnteredDescription(event.target.value)
};
const deadlineChangeHandler = (event) => {
setEnteredDeadline(event.target.value)
}
const startTimeChangeHandler = (event) => {
setEnteredStartTime(event.target.value);
}
const endTimeChangeHandler = (event) => {
setEnteredEndTime(event.target.value);
}
const colorChangeHandler = (event) => {
setEnteredColor(event.target.value);
}
const submitHandler = (event) => {
event.preventDefault();
const taskData = {
title: enteredTitle,
priority: enteredPriority,
description: enteredDescription,
due_date: new Date(enteredDeadline),
start: new Date(enteredStartTime),
end: new Date(enteredEndTime),
color: enteredColor,
};
console.log(taskData);
setEnteredTitle('');
setEnteredPriority('');
setEnteredDescription('');
setEnteredDeadline('');
setEnteredStartTime('');
setEnteredEndTime('');
setEnteredColor('#');
const requestBody = {
query: `
mutation {
createTask(taskInput: {title: "${enteredTitle}", description: "${enteredPriority}", priority: "${enteredDescription}", due_date: "${enteredDeadline}", start: "${enteredStartTime}", end: "${enteredEndTime}", color: "${enteredColor}"} ) {
_id
title
description
priority
due_date
start
end
color
creator {
id
email
}
}
}
`
};
fetch('http://localhost:5000/graphql', {
method: 'POST',
body: JSON.stringify(requestBody),
headers: {
'Content-Type': 'application/json'
}
})
.then(res => {
if (res.status !== 200 && res.status !== 201) {
throw new Error('Failed!');
}
return res.json();
})
.then(resData => {
this.fetchTasks();
})
.catch(err => {
console.log(err);
});
};
return (
<React.Fragment>
<div style={{marginTop:'118px'}} />
<Card >
<Card.Body>
<h3>Add Task</h3>
<p style={{opacity: "70%"}}>You can add items in the form below. These tasks will automatically be added to your task list and your calendar.</p>
<hr className="mt-4 mb-2" />
<Col>
<Row className="mt-2">
<form className="p-2" onSubmit={submitHandler}>
<Row>
<OverlayTrigger
placement="top"
overlay={<Tooltip>Enter a title/name for your task.</Tooltip>}>
<Col md={8}>
<FormInput
name="title"
label="Title"
placeholder="Enter title"
type="text"
containerClass="mb-3"
className="form-control form-control-light"
key="title"
value={enteredTitle}
onChange={titleChangeHandler}
/>
</Col>
</OverlayTrigger>
<OverlayTrigger
placement="top"
overlay={<Tooltip>Set a priority status to your task.</Tooltip>}>
<Col md={4}>
<FormInput
name="priority"
label="Priority"
type="select"
containerClass="mb-3"
className="form-select form-control-light"
key="priority"
value={enteredPriority}
onChange={priorityChangeHandler}
>
<option>Select</option>
<option>Low</option>
<option>Medium</option>
<option>High</option>
</FormInput>
</Col>
</OverlayTrigger>
</Row>
<OverlayTrigger
placement="top"
overlay={<Tooltip>Enter a description to explain details about the task.</Tooltip>}>
<Col>
<FormInput
name="description"
label="Description"
type="textarea"
containerClass="mb-3"
className="form-control form-control-light"
rows="3"
key="description"
value={enteredDescription}
onChange={descriptionChangeHandler}
/>
</Col>
</OverlayTrigger>
<OverlayTrigger
placement="top"
overlay={<Tooltip>Enter the date when the task has to be finished.</Tooltip>}>
<div className="form-group">
<FormInput
name="dueDate"
label="Due Date"
type="date"
value={enteredDeadline}
onChange={deadlineChangeHandler}>
</FormInput>
</div>
</OverlayTrigger>
<br />
<Row>
<OverlayTrigger
placement="top"
overlay={<Tooltip>Set a start time for your task. The task will be listed in your personal calendar accordingly.</Tooltip>}>
<Col md={6}>
<div className="form-group">
<label className="form-label">Start time</label> <br />
<FormInput
type="datetime-local"
value={enteredStartTime}
onChange={startTimeChangeHandler}
/>
</div>
</Col>
</OverlayTrigger>
<OverlayTrigger
placement="top"
overlay={<Tooltip>Set an end time for your task. The task will be listed in your personal calendar accordingly.</Tooltip>}>
<Col md={6}>
<div className="form-group">
<label className="form-label">End time</label> <br />
<FormInput
type="datetime-local"
value={enteredEndTime}
onChange={endTimeChangeHandler}
/>
</div>
</Col>
</OverlayTrigger>
</Row>
<br />
<Row>
<OverlayTrigger
placement="top"
overlay={<Tooltip>Set the color with which you want your task to appear in the calendar.</Tooltip>}>
<Col md={6}>
<div className="form-group">
<label className="form-label">Color</label> <br />
<FormInput
type="color"
// value={enteredColor}
onChange={colorChangeHandler}
>
</FormInput>
{/* <CirclePicker /> */}
</div>
</Col>
</OverlayTrigger>
</Row>
<Col>
<button style={{marginTop: '50px', marginLeft: "23%", width: "300px"}} type="submit" className="btn btn-sm btn-success">
<i className="uil uil-message me-1"></i>Add Task
</button>
</Col>
</form>
</Row>
</Col>
</Card.Body>
</Card>
</React.Fragment>
);
};
export default Task;
Right now, I can submit and log the formdata to my console in the form of an object so I know the technique behind it works. However, I just can't seem to manage inserting it into my actual database.
If someone is able to help me out it would be wildly appreciated!
Kind regards,
Abbeneji
Solution 1:[1]
On the submitHandler, I can see that you have created a const taskData for managing your inputs, well!. you logged taskData on console seems fine on console as well, and again you set them empty and reusing that UseState const on request body, may they already set empty there. Also look at the payload data(Next after Headers tab) and compare it with the api request flow, which may helpful for you to debugging. There may be a chance of request payload formed incorrectly.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Hari Upreti |
