how to solve "Cannot PUT /" - javascript

I am trying to update local database in mongodb. In my project I want to update my data here is the code.
second part is the edit part that i use to redirect my update data. It don't show any error so i can not find any problem to fix.All project in node.js, and use handelbar template , mongoose as database
:
const express = require('express')
const app = express()
const exphbs = require('express-handlebars');
const mongoose = require('mongoose')
const path = require('path')
const Idendity = require('./db/db.js')
const methodOverride = require('method-override')
app.use(methodOverride('_method'))
app.use(express.static( __dirname + "/public"));
app.use(express.urlencoded({
extended: false
}))
app.engine('.hbs', exphbs({
extname: '.hbs'
}))
app.set('view engine', '.hbs')
async function connectDB() {
try {
await mongoose.connect('mongodb://localhost:27017/Idendity', {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
useCreateIndex: true
})
console.log('database is connected')
} catch (error) {
console.log(error)
}
}
connectDB()
app.get('/', async (req, res) => {
const idendity = await Idendity.find()
const idendities = {
data: idendity.map(element => {return{id:element._id,name:element.name,email:element.email,profession:element.profession}} )
}
//console.log(idendities.data)
res.render('home', {
ID: idendities.data,
title: 'Contact App'
})
})
app.post('/', async (req, res) => {
const idendity = new Idendity({
...req.body
})
await idendity.save()
res.redirect('/')
})
app.get('/edit/:id',async (req,res)=>{
const id = req.params.id
const idendity = await Idendity.findById(id)
const contex = {name:idendity.name,email:idendity.email,profession:idendity.profession}
if(idendity){
res.render('edit',{
idendity:contex
})
}else{
res.send('404 not found')
}
})
app.put('/edit/:id',async (req,res)=>{
const id = req.params.id
const value = req.body
const newIdendity = await Idendity.findByIdAndUpdate(id,value,{ useFindAndModify:false})
console.log(value)
if(newIdendity){
res.redirect(`/edit/${id}`)
}else{
res.send('404 not found')
}
})
app.listen(8000, () => {
console.log('port is listening')
})
//////////////////////////////////////////////////////
<div class="container">
{{#with idendity}}
<form action="/?_method=PUT" method="POST">
<label for="name">name</label><br>
<input type="text" name="name" id="name" value={{name}}><br>
<label for="email">email</label><br>
<input type="text" name="email" id="email" value={{email}}><br>
<label for="profession">profession</label> <br>
<input type="text" name="profession" id="profession" value={{profession}}><br>
<button class="btn btn-primary my-3">add</button>
</form>{{/with}}
cancel
</div>

you can send put request to the given route because you don't have any put method attached to that route you are trying to access.
you have to have an
app.put("/",async(req,res)=>{
//code
})
or you can use
// this will be accessible by all HTTP methods
app.use("/",async(req,res)=>{
//code
})
in your code to be able to send a put request to the server.

Related

POST request returns null values (node.js)

POST requests return null. The req.body..... values are undefined. I tried to verify it arrives to the server in JSON format, but
i am not sure I am doing it in a right way.... :-(
Thanx a lot for help, amigos!
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const bodyParser = require('body-parser');
const cors = require("cors");
const indexRouter = require('./routes/index');
const usersRouter = require('./routes/users');
var app = express();
app.set('view engine', 'ejs')
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(bodyParser.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
const { MongoClient } = require("mongodb");
const uri = "mongod...the string is ok....y";
const client = new MongoClient(uri);
const database = client.db('holdocsDB');
const records = database.collection('records');
app.post("/users", async (req, res) => {
console.log('hola pooost');
console.log("req.body.age: " + req.body.age);
try {
// create a document to insert
const newRecord = {
firstName: req.body.firstName,
age: req.body.age
}
const result = await records.insertOne(newRecord);
console.log(`A document was inserted with the _id: ${result.insertedId}`);
// } finally {
// await client.close();
// }
} catch {
(e) => (console.error(e));
}
});
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.json('error');
});
module.exports = app;
When I hardcode some values to be posted in express POST route (instead of extracting the values from req.body) - it works well.
function RecordSearchBar() {
const [form, setForm] = useState({
firstName: "",
age: 0
});
// const navigate = useNavigate();
function updateForm(value) {
return setForm((prev) => {
return { ...prev, ...value };
});
}
async function onSubmit(e) {
e.preventDefault();
const newPerson = { ...form };
await fetch("http://localhost:3001/users/add", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(newPerson),
})
.catch(error => {
window.alert(error);
return;
});
setForm({ firstName: "", age: ""});
// navigate("/users");
}
return (
<>
<h2>Search records:</h2>
<form onSubmit={onSubmit} id='search-form'>
<div className="form-group">
<label htmlFor="firstName">First name</label>
<input
type="text"
className="form-control"
id="name"
value={form.name}
onChange={(e) => updateForm({ name: e.target.value })}
/>
</div>
<div className="form-group">
<label htmlFor="age">Age</label>
<input
type="number"
className="form-control"
id="position"
value={form.position}
onChange={(e) => updateForm({ position: e.target.value })}
/>
</div>
<div className="form-group">
<input
type="submit"
value="Add record"
className="btn btn-primary"
/>
</div>
</form>
</>
Solved! I had to correct the type conversion of request body using JSON.parse() and JSON.stringify():
app.post("/users", async (req, res) => {
console.log("req.body: " + JSON.stringify(req.body));
let newRecordStringified = JSON.stringify(req.body)
try {
// create a document to insert
const newRecord = {
firstName: req.body.firstName,
age: req.body.age
// firstName: "Mamile",
// age: 33
}
const result = await records.insertOne(JSON.parse(newRecordStringified));
console.log(`A document was inserted with the _id: ${result.insertedId}`);
// } finally {
// await client.close();
// }
} catch {
(e) => (console.error(e));
}
})

Can't create new document on POST (mongoose/express)

Check My Node.js code Please I want to Save Contact page data in mongoose compass this don't throw any error but also not saving data
<form action="/" class="contact_form grid" method="POST">
HTML IS TOTALLY CORRECT WRITTEN I THINK PLEASE TELL ME WHATS WRONG IN THIS APP.JS CODE
const express = require('express');
const mongoose = require('mongoose');
const app = express();
const bodyparser = require('body-parser')
const path = require('path');
mongoose.connect('mongodb://localhost:27017/ContactPage');
const port = 3000;
var contactSchema= new mongoose.Schema({
name:{type:String},
email:{type:String},
project:{type:String},
message:{type:String}
});
var Contact = mongoose.model('Contact', contactSchema);
module.exports = Contact;
app.use('/static', express.static('static')) // For serving static files
app.use(express.urlencoded({extended: true}))
app.set('view engine', 'ejs');
app.get('/', function(req,res){
res.sendFile(path.join(__dirname, "index.html"))
});
app.post('/',(req,res)=>{
var myData = new Contact(req.body);
myData.save().then(()=>{
res.send(req.body)
}).catch(()=>{
res.status(400).send(req.body);
});
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
Check My Node.js code Please I want to Save Contact page data in mongoose compass this don't throw any error but also not saving data
<form action="/" class="contact_form grid" method="POST">
<div class="contact_inputs grid">
<div class="contact_content">
<label for="" class="contact_label">Name</label>
<input type="text" name= "name" class="contact_input">
</div>
<div class="contact_content">
<label for="" class="contact_label">Email</label>
<input type="email"name="email" class="contact_input">
</div>
</div>
<div class="contact_content">
<label for="" class="contact_label">Project</label>
<input type="text" name="project" class="contact_input">
</div>
<div class="contact_content">
<label for="" class="contact_label">Message</label>
<textarea name="" id="" cols="0" rows="7" name = "message" class="contact_input"></textarea>
</div>
<div>
<a href="" class="button button--flex">
Send Message
<i class="fas fa-paper-plane button_icon"></i>
</a>
</div>
</form>
#1 you are not submitting from HTML, so instead of:
<div>
<a href="" class="button button--flex">
Send Message
<i class="fas fa-paper-plane button_icon"></i>
</a>
</div>
write:
<button type="submit">
Send Message
</button>
#2 express improvements
contactSchema file:
const mongoose = require('mongoose')
var contactSchema = new mongoose.Schema({
name: { type: String },
email: { type: String },
project: { type: String },
message: { type: String }
});
module.exports = mongoose.model('Contact', contactSchema);
app file:
const express = require('express');
const mongoose = require('mongoose');
const bodyparser = require('body-parser')
const path = require('path');
const port = 3000;
const app = express();
app.use('/static', express.static('static')) // For serving static files
app.use(express.urlencoded({ extended: true }))
app.set('view engine', 'ejs');
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, "index.html"))
});
app.post('/', (req, res) => {
var { name, email, project, message } = req.body;
var myData = new Contact({
name,
email,
project,
message,
});
myData.save().then((newData) => {
res.send(newData)
}).catch((err) => {
res.status(400).send("Error: ", err, " , Data: ", req.body);
});
});
app.listen(port, () => {
mongoose.connect('mongodb://localhost:27017/ContactPage')
.then(() => console.log("Server & DB listening at http://localhost:${port}"))
.catch(err => console.log(err));
})

Using React.js, Node.js and Multer, how can I console log 'req.file' on the server?

I am building a MERN app and when I try to console.log(req.file) on the server I get undefined. I've checked the multer github page and other SO articles, but I still haven't been able to figure it out using React hooks and jsx. I'm newish to SO so, I will add edits since I can't comment yet.
Here is a link to the branch in GitHub if you want to see all the files. https://github.com/BenjDG/puzzle-gallery/tree/so
I'm new to multer and react so any help is appreciated.
Here is my code:
server\controllers\puzzleController.js
const multer = require('multer');
const upload = multer({ dest: './uploads'});
const db = require('../models');
const fs = require('fs');
const type = upload.single('picFile');
// Defining methods for the puzzleController
module.exports = {
findAll: function (req, res) {
db.Puzzle
.find(req.query)
.then(dbModel => res.json(dbModel))
.catch(err => res.status(422).json(err));
},
save: (type, function (req, res) {
// console.log(req);
console.log(req.file);
console.log(req.body);
res.sendStatus(200);
}),
remove: function (req, res) {
db.Puzzle
.findById({ _id: req.params.id })
.then(dbModel => dbModel.remove())
.then(dbModel => res.json(dbModel))
.catch(err => res.status(422).json(err));
}
};
client\src\components\gallery\index.js
import React, { useState } from 'react';
import './styles.css';
import API from '../../services/API';
export default function Gallery () {
const [picFile, setPicFile] = useState();
const handleGetClick = async () => {
API.findAll()
.then(res => {
console.log(res)
})
.catch(err => console.error(err))
}
const handleUploadClick = async (e) => {
e.preventDefault();
// console.log(picFile);
// create new formData instance
const bodyFormData = new FormData();
// append single file to formData instance
bodyFormData.append('picFile', picFile.selectedFile);
// log items in formData object
for (const element of bodyFormData) {
console.log(element);
}
// send formData obj to axios function
API.save(bodyFormData)
.then(res => {
//console.log(res)
})
.catch(err => console.error(err))
}
const onFileChange = (e) => {
console.log(`e.target.files[0]`, e.target.files[0])
setPicFile({ selectedFile: e.target.files[0] });
}
return (
<div>
<h1>My Puzzle Gallery</h1>
<form encType='multipart/form-data'>
<input type='file' name='picFile' onChange={onFileChange} />
<br />
<br />
<button onClick={handleUploadClick}>Upload a picture</button>
</form>
<br />
<br />
<button onClick={handleGetClick}>Get pictures</button>
<br />
<br />
<img src='https://placekitten.com/640/360' alt='kitten' />
</div>
);
}
client\src\services\API.js
import axios from 'axios';
const API = {
login: (username, password) => {
const obj = {
username: username,
password: password
};
return axios.post('/api/auth/login', obj);
},
register: (username, password) => {
const obj = {
username: username,
password: password
};
return axios.post('/api/auth/register', obj);
},
logout: function () {
return axios.get('api/auth/logout');
},
save: function (form) {
return axios.post('api/puzzle/', form).catch(err=>console.error(err));
},
findAll: function () {
return axios.get('api/puzzle/');
},
}
export default API;
server\routes\api\puzzle\index.js
const router = require('express').Router();
const puzzleController = require('../../../controllers/puzzleController');
// Matches with '/api/puzzle'
router.route('/')
.get(puzzleController.findAll)
.post(puzzleController.save);
// Matches with '/api/books/:id'
router.route('/delete/:id')
.delete(puzzleController.remove);
module.exports = router;
server\server.js
const path = require('path');
const express = require('express');
const passport = require('./config/passport');
const mongoose = require('mongoose');
const cors = require('cors');
const session = require('express-session');
const helmet = require('helmet');
const morgan = require('morgan');
const corsOptions = require('./config/cors.js');
const routes = require('./routes');
const { v1: uuidv1 } = require('uuid');
// console.log(uuidv1());
const PORT = process.env.PORT || 3001;
const app = express();
mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost/puzzlegallery', {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: false
});
mongoose.set("useCreateIndex", true);
// Define middleware here
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(helmet({ contentSecurityPolicy: false }));
app.use(session({ secret: 'sassy', resave: false, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use(cors(corsOptions));
app.use(morgan('dev'));
app.use(routes);
// for Reactjs ##################
// Serve up static assets (usually on heroku)
if (process.env.NODE_ENV === 'production') {
app.use(express.static('client/build'));
}
// #################################################
if (process.env.NODE_ENV === 'production') {
app.get('*', (_, res) => {
res.sendFile(path.join(__dirname, '../client/build/index.html'));
});
}
app.listen(PORT, (err) => {
if (err) throw err;
console.log(
`🌎 Server is Ready and Listening on http://localhost:${PORT}`
); // eslint-disable-line no-console
});
EDIT:
This seemed to work. Thanks again!!
const path = require('path');
const router = require('express').Router();
const puzzleController = require('../../../controllers/puzzleController');
const multer = require('multer');
const { v1: uuidv1 } = require('uuid');
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, path.join(__dirname, '../../../../tmp/my-uploads'))
},
filename: function (req, file, cb) {
cb(null, uuidv1())
}
})
const upload = multer({ storage: storage });
// Matches with '/api/puzzle'
router.route('/')
.get(puzzleController.findAll)
// Matches with '/api/books/:id'
router.route('/delete/:id')
.delete(puzzleController.remove);
router.use(upload.single('picFile'));
router.route('/')
.post(puzzleController.save);
module.exports = router;
you cannot call the middleware inside the save function like this.
I cloned your repo and added the following code in server.js and it's working fine and I got the value in the req.file.
const multer = require('multer');
const upload = multer({ dest: 'uploads/'});
app.post('/api/puzzle/', upload.single('pictureFile'),(req,res,next)=>{
console.log("req.file22222222", req.file);
})

Cannot POST form - ExpressJS

I'm learing ExpressJS, i want to do the login part , but i gave me this
Cannot POST /login
im using the post method why it gave me this error
here a detailed post , thank you in advance for helping me
html part
<form method="POST">
<div class="container">
<label for="uname"><b>Username</b></label>
<input type="text" placeholder="Enter Username" name="name" >
<label for="psw"><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="password">
<button type="submit">Login</button>
</div>
</form>
The route.js
router.post('/login'),(req,res)=>{
var username= req.body.name;
var password = req.body.password;
con.query('SELECT * FROM authentication WHERE username = ?',username, function (error, results, fields) {
if (error) {
// console.log("error ocurred",error);
res.send({
"code":400,
"failed":"error ocurred"
})
}else{
// console.log('The solution is: ', results);
if(results.length >0){
if(results[0].password == password){
res.send({
"code":200,
"success":"login sucessfull"
});
}
else{
res.send({
"code":204,
"success":"username and password does not match"
});
}
}
else{
res.send({
"code":204,
"success":"username does not exits"
});
}
}
});
}
module.exports = router
index.js
const express = require('express');
const app = express()
const bodyParser = require("body-parser");
const indexRouter = require('./routes/route')
const con = require('./models/db')
con.connect(function(err) {
if (err) {
return console.error('error: ' + err.message);
}
console.log('Connected to the MySQL server.');
});
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
var exphbs = require('express-handlebars');
console.log(__dirname)
app.use('/',express.static(__dirname + '/public'));
app.engine('handlebars', exphbs());
app.set('view engine', 'handlebars');
app.use('/',indexRouter)
const PORT = 5000;
app.listen(PORT,()=>console.log('it started on 5000'))
when trying to post this form i'm getting:
Cannot POST /login
what am i missing here?
You should handle current page, not '/login' page in route.js :
router.post('/', //...
Instead of writing
router.post('/login', //...
Because you sent the form data to the current page not to the '/login' page
Why current page ?
Because, you didn't define action attribute in your form
You need to define form action
<form action="/login" method="post">
But I recommend you to use js for sending requests
fetch('/login', {
method: 'POST',
body: JSON.stringify(yourFormData),
// ...another Opts if it needs
})
Also it can be problem with your server code because I don't see defining router in indexRouter file, you should add it:
const express = require('express');
const router = express.Router();
// then your code:
router.post('/login', loginController);
But you can add this line for check post requests:
app.post('/login', (req, res) => {
res.status(201).json(req.body); // or console.log
});

Express req.body undefined when passing to user model

Using Express 4.14 I have a simple html form accepting username and password. I want to pass that info to a function that inserts it into my psql database. But first I verify if that user is already in the db. I keep getting the error at "let uname = req.body.name;"
Thanks for the help.
HMTL form:
<div>
<form class="" action="/register" method="post">
<input class="text-input" type="text" name="user[username]" value="" placeholder="Username">
<input class="text-input" type="password" name="user[password]" value="" placeholder="Password">
<input type="submit" value="Sign up">
</form>
</div>
my function to insert into db:
verifyUser(req, res, next) {
let uname = req.body.name;
db.any(`SELECT * FROM users WHERE name = uname LIMIT 1`)
.then(() => {
next();
})
my server setup:
'use strict'
require('dotenv').config({ silent: true });
const bodyParser = require('body-parser');
const express = require('express');
const logger = require('morgan');
const path = require('path');
const app = express();
const authRouter = require('./routes/auth/auth.js');
const loginRouter = require('./routes/login/login.js');
const apiRouter = require('./routes/api/apiRoute.js');
const profileRouter = require('./routes/profile/profile.js');
const regRouter = require('./routes/register/register.js');
const PORT = process.argv[2] || process.env.port || 3000;
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'dist')));
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.listen(PORT, () => { console.log('app is listening on 3k')});
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public/landing.html'));
});
app.get('/login', (req, res) => {
res.sendFile(path.join(__dirname, 'public/login.html'));
});
app.get('/signup', (req, res) => {
res.sendFile(path.join(__dirname, 'public/signup.html'));
});
app.use('/api', apiRouter);
app.use('/auth', authRouter);
app.use('/login', loginRouter);
app.use('/register', regRouter);
app.use('/profile', profileRouter);
regRouter: None of those console.logs actually return anything. So, there's that.
const regRouter = require('express').Router();
const { createUser } = require('../../models/user_model');
regRouter.get('/', (req, res) => {
console.log('register line 5')
res.render('register');
});
regRouter.post('/', createUser, (req, res) => {
console.log('register line 10')
res.render('landing');
});
module.exports = regRouter;
createUser:
function createUser(req, res, next) {
console.log('create user line 10');
let uname = req.body.name;
console.log('body', req.body);
let encryption = bcrypt.hashSync(req.body.password, SECRET);
db.any(`INSERT INTO users
(name, password)
VALUES ($1, $2);` [uname, encryption])
.then(() => {
next();
})
.catch(error => next(error));
};
In your html there isn't any input field with name attribute set to "name" or "password.
<input class="text-input" type="text" name="name" value="" placeholder="Username">
<input class="text-input" type="password" name="password" value="" placeholder="Password">

Categories

Resources