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
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.
Related
i want to display the file path as input value when working on editing
the reason is that when i click on edit button all the others values (data) of camp is put into the input fields but the url of camp is not placing in the input filed
This is my camp.ts file
form = new FormGroup({
title:new FormControl('',),
images: new FormControl(''),
location: new FormControl(''),
price: new FormControl(''),
description: new FormControl('')
})
public uploadFile(event: Event): void {
const input = event.target as HTMLInputElement;
if (!input.files?.length) {
return;
}
const file = input.files[0];
this.form.patchValue({
images: file
});
this.form.get('images');
}
ngOnInit(): void {
this.id = this.route.snapshot.params.id;
this.getData();
}
get f(){
return this.form.controls;
}
getData(){
this.campgroundService.getDataById(this.id).subscribe(res => {
this.data = res;
this.campground = this.data;
this.form = new FormGroup({
title: new FormControl(this.campground.title, Validators.required),
images: new FormControl(this.campground.images[0].url , Validators.required),
location: new FormControl(this.campground.location, Validators.required),
price: new FormControl(this.campground.price, Validators.required),
description: new FormControl(this.campground.description, Validators.required)
});
console.log('Fetching Form Values from backend',this.form.value);
console.log('file data = ', this.campground.images[0].url);
});
}
This is my camp.html file
<div class="form-group" >
<label for="title"> Enter Title </label>
<input type="text" formControlName="title" placeholder="Enter Title" [ngClass]="{'is-invalid':submitted && f.title.errors}" class="form-control">
<div *ngIf="submitted && f.title.errors" class="invalid-feedback">
<div *ngIf="f.title.errors.required">
Title Is Required!
</div>
</div>
</div>
<!-- Image Input -->
<div class="form-group">
<label for="image"> Selcet Image </label>
<input type="file" name="images" id="image" (change)="uploadFile($event)" class="form-control" accept="image/x-png,image/gif,image/jpeg"/>
</div>
You need to add formControlName="images" to the second input:
<input
class="form-control"
formControlName="images"
type="file"
name="images"
id="image"
(change)="uploadFile($event)"
accept="image/x-png,image/gif,image/jpeg"
>
By the way, maybe it would be better if you do the form initialization at the beginning of your code, already with validators.
Then, when yo get the data response, you only have to update the values of the fields and do not re-create the form-controls for them.
Something like that:
form = new FormGroup({
title:new FormControl('', Validators.required),
images: new FormControl('', Validators.required),
location: new FormControl('', Validators.required),
price: new FormControl('', Validators.required),
description: new FormControl('', Validators.required)
})
...
getData(){
this.campgroundService.getDataById(this.id)
.subscribe(
res => {
this.data = res;
this.campground = this.data;
this.form.patchValue({
title: this.campground.title,
images: this.campground.images[0].url,
location: this.campground.location,
price: this.campground.price,
description: this.campground.description,
});
console.log('Fetching Form Values from backend',this.form.value);
console.log('file data = ', this.campground.images[0].url);
});
}
I have three input to obtain three different values. Im using express.js , node.js, mongodb and ejs templates.
<form action="/save-profile/<%= user.id %>/<%= user.name %>/<%= user.lastname %>/<%= user.description %>" method="POST">
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon1">Name</span><%= user.username %>
<input type="text" class="form-control" placeholder="'John'" aria-label="Username" name="username">
<span class="input-group-text">lastName</span><%= user.lastname %>
<input type="text" class="form-control" placeholder="" aria-label="Server" name="lastname">
</div>
<div class="input-group">
<span class="input-group-text">Description:</span>
<textarea class="form-control" aria-label="With textarea" placeholder="" name="description"><%= user.description %></textarea>
</div>
</p><br>
<button class="btn btn-primary mb-10 btn-lg">Save</button>
</div>
</div>
In js file:
router.post('/save-profile', async (req, res) => {
const profile_id = await User.findById({ _id: req.body.id })
const updatedName = await User.findOneAndUpdate({ username: req.body.username})
const updatedlastname = await User.findOneAndUpdate({ apellido: req.body.lastname })
const updatedDescription = await User.findOneAndUpdate({ description: req.body.description })
console.log(profile_id,updatedName,updatedApellido,updatedDescription)
res.redirect('/profile')})
I tried to do it with a get but it didn't work
Firstly, action attribute in the form tag accepts the path where you are handling the form data. You only need to pass the user.id, there's no need to pass the other fields for this use-case.
<form action="/save-profile/<%= user.id %>" method="POST">
...
</form>
Secondly, in your route handler, the database record can be updated using only a single findOneAndUpdate call. You don't need to call it multiple times for every field if you're only going to update a single record.
The path written in action attribute will appear as /save-profile/1, for instance, in your route handler. Value preceding /save-profile/ i.e. 1 can be accessed by modifying the path in route handler as /save-profile/:id and in the callback you can get it by req.params.id
Finally you have this.
router.post('/save-profile/:id', async (req, res) => {
const response = await User.findOneAndUpdate(
{ _id: req.params.id },
{
username: req.body.username,
apellido: req.body.lastname,
description: req.body.description
},
{ new: true }
)
// Do something with response
res.redirect('/profile')
})
I'm creating a simple user registration page where account level (1 = user & 2= admin) is putting up an error when i post a request through axios. This seemed to be a somewhat common error corrected mostly by having a default number value in the schema, which I already have. Furthermore, I do not come across this error when I test with postman.
Error:
Error: users validation failed: accLevel: Cast to Number failed for value "NaN" (type number) at path "accLevel", username: Path `username` is required., password: Path `password` is required.
at ValidationError.inspect (E:\SLIIT\Y2S2\ITP\FitnessFactory\backend\node_modules\mongoose\lib\error\validation.js:48:26)
However, when I test with post man I do not get this error and mongodb works. Like so. It also works for accLevel in int form.
{
"username": "Mary",
"password": "mary",
"accType": "customer",
"accLevel": "1"
}
Heres the user schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema({
username : {
type: String,
required: true
},
password : {
type: String,
required: true
},
accType: {
enum: ["customer", "instructor"],
//required: true
},
accLevel: {
type: Number,
default: 1
}
})
const User = mongoose.model('users', userSchema);
module.exports = User;
Heres the user route and controller file
const router = require("express").Router();
let User = require("../models/user");
//createUserAccount
router.route("/createUserAccount").post((req,res) => {
const username = req.body.username;
const password = req.body.password;
const accType = req.body.accType;
const accLevel = Number(req.body.accLevel);
const newUser = new User({
username,
password,
accType,
accLevel
})
newUser.save().then(() => {
res.json("User account created")
}).catch((err) => {
console.log(err);
})
})
//login
router.route("/userLogin/:id").post(async(req,res) => {
})
module.exports = router;
Heres is the component file for createUserAccount.jsx
//Create account component
import React, {useState} from "react";
import axios from 'axios';
//bootstrap imports
import Form from 'react-bootstrap/Form';
import Button from "react-bootstrap/Button";
import Container from 'react-bootstrap/Container';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
//custom styles
import '../styles/CreateAccount.css';
function CreateAccount(){
//set states
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [reEnterPassword, setReEnterPassword] = useState("");
const [accType, setAccType] = useState("");
const [accLevel, setAccLevel] = useState("");
//handle change
function handleSubmit(e){
e.preventDefault();
if (password !== reEnterPassword){
alert("Passwords do not match!")
}
else if (accType === ''){
alert("Select account type!")
}
else if (accLevel === ''){
alert("Select account level!")
}
else{
const newUser = {
username,
password,
accType,
accLevel
}
console.log(newUser);
axios.post("http://localhost:8070/user/createUserAccount").then(()=>{
alert("account created")
}).catch((err)=>{
alert(err)
})
}
}
return (
<div>
<div className='createAccountBlock'>
<h1>Create Account</h1>
<form onSubmit={handleSubmit}>
<Form.Group name="username" className="mb-3" controlId="username">
<Form.Label>Username</Form.Label>
<Form.Control type="text" placeholder="Enter Username" className='formText'
onChange = {(e)=>{
setUsername(e.target.value);
}}
/>
</Form.Group>
<Form.Group name="password" className="mb-3" controlId="password">
<Form.Label>Password</Form.Label>
<Form.Control type="password" placeholder="Password" className='formText'
onChange = {(e)=>{
setPassword(e.target.value);
}}
/>
</Form.Group>
<Form.Group name="reEnterPassword" className="mb-3" controlId="reEnterPassword">
<Form.Label>Re-enter Password</Form.Label>
<Form.Control type="password" placeholder="Re-enter Password" className='formText'
onChange = {(e)=>{
setReEnterPassword(e.target.value);
}}
/>
</Form.Group>
<Container>
<Row>
<Col>
<Form.Select name="accType" aria-label="Default select example"
onChange = {(e)=>{
setAccType(e.target.value);
}}
>
<option>Select Account Type</option>
<option value="customer">Customer</option>
<option value="instructor">Instructor</option>
</Form.Select>
</Col>
<Col>
<Form.Select name="accLevel" aria-label="Default select example"
onChange = {(e)=>{
setAccLevel(e.target.value);
}}
>
<option>Select Account Level</option>
<option value="1">Level 1 (user)</option>
<option value="2">Level 2 (admin)</option>
</Form.Select>
</Col>
</Row>
<div className='flex-container'>
<Button variant="primary" type="submit" className='btn1'>
Create Account
</Button>
</div>
</Container>
</form>
</div>
</div>
);
}
export default CreateAccount;
It works when I test with postman for both int and string, but fails using axios. Btw, I tried parseInt from the frontend as well.
Any Ideas?
It doesn't look like you're sending a data object in your POST request.
axios.post("http://localhost:8070/user/createUserAccount").then(()=>{
alert("account created")
}).catch((err)=>{
alert(err)
})
axios.post needs a second argument of the object that you are sending.
I am new to learning React. I have build a small application which includes React,Node and MongoDB. I have two modules here, the Create data and the Edit data. My question is regarding the Select component from Reacts's built in library. When I create a user, I enter his availability time slots(isMulti in Select) from a component. On Submit, this data along with the the slots is getting inserted in the Mongo Db.This is all fine. I am having problem when loading the page for edit. How to make the previously selected items from dropdown show up on page load. The other fields show up fine with componentDidMount().
Here is what my update module looks like-
// eslint-disable-next-line
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import Select from 'react-select';
import DatePicker from 'react-datepicker';
import "react-datepicker/dist/react-datepicker.css";
// Connecting from front end to backend with Axios
import axios from "axios";
export default class EditPanel extends Component {
constructor(props) {
super(props);
//defining this
this.onChangefield1 = this.onChangefield1.bind(this);
this.onChangefield2 = this.onChangefield2.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.handleChange=this.handleChange.bind(this);
this.state = {
field1: "",
field2: "",
timeSlots:[],
filterOptions:[
{ label:"9:00am to 10:00am", value: "9:00am to 10:00am" },
{ label: "10:00am to 11:00am", value: "10:00am to 11:00am" },
{ label: "11:00am to 12:00pm", value: "11:00am to 12:00pm" },
{ label: "12:00pm to 01:00pm", value: "12:00pm to 01:00pm" },
{ label: "01:00pm to 02:00pm", value: "01:00pm to 02:00pm" },
],
selectedOption:[]
}
}
componentDidMount() {
console.log("inside componentmount");
axios.get('http://localhost:5000/someEndpoint/' + this.props.match.params.id)
.then(response => {
this.setState({
field1: response.data.field1,
field2: response.data.field2,
mailId: response.data.mailId,
timeSlots:response.data.timeSlots,
selectedOption: response.data.timeSlots,
})
console.log("Meow"+response.data.timeSlots);
})
.catch(function (error) {
console.log(error);
})
}
onChangefield1(e) {
this.setState({ field1: e.target.value });
}
onChangefield2(e) {
this.setState({ field2: e.target.value });
}
// This is for insertion of any new selected list items
handleChange = selectedOption => {
console.log(selectedOption.value);
this.setState({ selectedOption: selectedOption.value }); // selected option value
console.log(selectedOption);
var dataArray = [];
for(var o in selectedOption) {
dataArray.push(selectedOption[o].value);
this.setState({ timeSlots: dataArray });
console.log(this.timeSlots);
}
};
onSubmit(e) {
e.preventDefault();
const panel =
{
field1: this.state.field1,
field2: this.state.field2,
timeSlots:this.state.timeSlots
}
axios.post('http://localhost:5000/someEndpoint/update/' + this.props.match.params.id, panel)
.then(res => console.log(res.data));
console.log("calling from edit");
window.location = '/';
}
render() {
return (
<div>
<h3>Edit Panel Info</h3>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>Field 1: </label>
<input type="text"
required
className="form-control"
value={this.state.field1}
onChange={this.onChangefield1}
/>
</div>
<div className="form-group">
<label>field2: </label>
<input
type="text"
className="form-control"
value={this.state.field1}
onChange={this.onChangefield2}
/>
</div>
<div className="form-group">
<label>Time Slots</label>
<div>
<Select
options={this.state.filterOptions} // Options to display in the dropdown
isMulti
value={this.state.selectedOption} // would like to see the values we have in DB
onChange={this.handleChange}
closeIcon="close"
/>
</div>
</div>
<div className="form-group">
<input type="submit" value="Edit Panel" className="btn btn-primary" />
</div>
</form>
</div>
)
enter code here
}
}`enter image description here`
[enter image description here][1]
[1]: https://i.stack.imgur.com/NliEH.png
The mongo db data looks like
timeSlots
:
Array
0
:
"10:00am to 11:00am"
1
:
"12:00pm to 01:00pm"
I have a form that is being used to edit and update the record of a specific Id and I'm able to access the Id within my GET method for my route with req.params.annotationId, but when I try to use the POST version of getting a parameter with req.body.annotationId I get a value returned of NULL. I also tried to use req.params.annotationId and it returned the :annotationId placeholder for the route. Is this because the field is not present in the form? which would make sense because body-parser looks for values present in the fields?
This is the resulting query from the POST method:
Executing (default): SELECT `annotation_id` AS `annotationId`, `annotation_date` AS `annotationDate`,`user_id` AS `userId`, `createdAt`, `updatedAt`, `userUserId` FROM `annotation` AS `annotation` WHERE `annotation`.`user_id` = 1 AND `annotation`.`annotation_id` = NULL LIMIT 1;
Here is my route:
appRoutes.route('/edit/:annotationId')
.get(function(req, res){
console.log('This is the url path ' + req.originalUrl);
console.log(req.params.annotationId);
models.Annotation.find({
where: {
userId: req.user.user_id,
annotationId: req.params.annotationId
},attributes: ['annotationId', 'annotationDate']
}).then(function(annotation){
res.render('pages/annotation-edit.hbs',{
annotation: annotation,
user: req.user,
editMode: req.originalUrl
});
})
})
.post(function(req, res){
console.log("POST method triggered");
console.log(req.params.annotationId);
models.Annotation.find({
where: {
userId: req.user.user_id,
annotationId: req.body.annotationId
}
}).then(function(annotation){
if (annotation) {
console.log("Annotation exists");
annotation.update({
annotationDate: req.body.annotationDate,
userId: req.user.user_id
}).success(function() {
console.log("Annotation Updated");
});
}
})
});
Here is my annotation model:
module.exports = function(sequelize, DataTypes) {
var Annotation = sequelize.define('annotation', {
annotationId: {
type: DataTypes.INTEGER,
field: 'annotation_id',
autoIncrement: true,
primaryKey: true
},
annotationDate: {
type: DataTypes.DATE,
field: 'annotation_date'
},
userId: {
type: DataTypes.STRING,
field: 'user_id'
}
},
{
freezeTableName: true,
},
classMethods: {
associate: function(db) {
Annotation.belongsTo(db.User)
}
}
});
return Annotation;
}
Here is the form for the POST request:
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="annotation-form">
<form action="/app/edit/:annotationId" method="post">
<div class="annotation-form-header">
<img class="user-image" src="http://placehold.it/80x80" alt="Generic placeholder image">
<label for="annotation-date">Annotation Date:</label>
<input type="date" name="annotationDate" id="annotation-form-date" value="{{annotation.annotationDate}}">
</div>
<button type="submit" id="create-annotation-button">Update Annotation</button>
</form>
req.body.annotationId with get annotationID from data in form like :
<form action="/app/edit" method="post">
<input name="annotationId" type="hidden" value="121313">
<div class="annotation-form-header">
<img class="user-image" src="http://placehold.it/80x80" alt="Generic placeholder image">
<label for="annotation-date">Annotation Date:</label>
<input type="date" name="annotationDate" id="annotation-form-date" value="{{annotation.annotationDate}}">
</div>
<button type="submit" id="create-annotation-button">Update Annotation</button>
</form>
```
req.params.annotationId get annotationID from URL : /edit/4465465
<form action="/app/edit/:annotationId" method="post"> <- invalid URL
The form should use the handlebars object to pass in the current Id selected like so,
<form action="/app/edit/{{annotation.annotationId}}" method="post">
<input name="annotationId" type="hidden" value="121313">
<div class="annotation-form-header">
<img class="user-image" src="http://placehold.it/80x80" alt="Generic placeholder image">
<label for="annotation-date">Annotation Date:</label>
<input type="date" name="annotationDate" id="annotation-form-date" value="{{annotation.annotationDate}}">
</div>
<button type="submit" id="create-annotation-button">Update Annotation</button>
</form>
The route should then be change from .find to .update:
.post(function(req, res){
console.log("POST method triggered");
console.log(req.params.annotationId);
models.Annotation.update({
annotationId: req.body.annotationId,
annotationDate: req.body.annotationDate,
},{where:{
userId: req.user.user_id,
annotationId: req.body.annotationId
}}).then(function(){
console.log("Annotation was Updated");
res.redirect('/app');
});
});