TypeError: Cannot read properties of undefined (reading 'id') - React App - node.js

I've trying to edit an entry of the data fetched from mysql and want to reflect if back in mysql db. For this im using post method of Axios. But im getting the following error when i try to edit the data and see for changes.
TypeError: Cannot read properties of undefined (reading 'id')
at C:\Users\Rahul01\Desktop\DBMS-PROJECT\BusTicketManagementSystem\server\index.js:123:23
at Layer.handle [as handle_request] (C:\Users\Rahul01\Desktop\DBMS-PROJECT\BusTicketManagementSystem\server\node_modules\express\lib\router\layer.js:95:5)
Here are the Codes
1.index.js
app.post('/admin/updatebus',(res,req)=>{
const id=req.body.id
const name=req.body.newbusname
const fromcity=req.body.newfromstation
const tocity=req.body.newtostation
const capacity=req.body.newcapacity+1
db.query("UPDATE bus SET busname=?,fromcity=?,tocity=?,capacity=? WHERE busid=? ",[name,fromcity,tocity,capacity,id+1],(err,result)=>{
if(err)
{
console.log(err);
res.send({op:f})
}
else
{
res.send({op:s});
}
})
})
2.Editbus.js
import Axios from 'axios'
import React, { useState } from 'react'
import { useParams } from 'react-router-dom'
export default function Editbus() {
const [newbusname, setnewbusname] = useState('')
const [newfromstation, setnewfromstation] = useState('')
const [newtostation, setnewtostation] = useState('')
const [newcapacity, setnewcapacity] = useState(0)
const {id}=useParams();
const handlesave=(e)=>{
// alert(key)
alert('Name'+newbusname+"\n From:"+newfromstation+"\nTo: "+newtostation+"\n Capacity: "+newcapacity)
Axios.post('http://localhost:3001/admin/updatebus',{
newbusname:newbusname,
newfromstation:newfromstation,
newtostation:newtostation,
newcapacity:newcapacity,
id:parseInt(id)
}).then((resp)=>{
if(resp.data.op==='s')
{
alert('Updated')
}
else
{
alert('Not Updated')
}
})
e.preventDefault()
}
return (
<>
<div class="container-contact100">
<div class="wrap-contact100">
<form class="contact100-form validate-form">
<span class="contact100-form-title">
Edit Bus {id}
</span>
<div class="wrap-input100 validate-input" data-validate="Name is required">
<input class="input100" type="text" name="name" onChange={e=>setnewbusname(e.target.value)} placeholder="New Bus Name" required/>
<span class="focus-input100"></span>
</div>
<div class="wrap-input100 validate-input" data-validate = "Valid email is required: ex#abc.xyz">
<input class="input100" type="text" name="email" onChange={e=>setnewfromstation(e.target.value)} placeholder="From Bus Stop" required/>
<span class="focus-input100"></span>
</div>
<div class="wrap-input100 validate-input" data-validate = "Valid email is required: ex#abc.xyz">
<input class="input100" type="text" name="email" onChange={e=>setnewtostation(e.target.value)} placeholder="To Bus Stop" required/>
<span class="focus-input100"></span>
</div>
<div class="wrap-input100 validate-input" data-validate = "Valid email is required: ex#abc.xyz">
<input class="input100" type="number" name="email" onChange={e=>setnewcapacity(e.target.value)} placeholder="New Capacity" required/>
<span class="focus-input100"></span>
</div>
<button onClick={handlesave}>Update</button>
</form>
</div>
</div>
<div id="dropDownSelect1"></div>
</>
)
}
In App.js
<Route exact path="/admin/editbus/:id" element={}>

It should be (req, res) instead of (res,req) in the .post handler.
Corrected Code:
app.post('/admin/updatebus',(req,res)=>{}
First Parameter should be for Request and second one for the Response.
Tip:
Include type='button' in the Submit Button so that the HTML form doesn't gets submitted.
<button type="button" onClick={handlesave}>Update</button>

Related

Using the useContext , it says object is not iterable (cannot read property Symbol(Symbol.iterator))?

When ever i am using useContext in the js file, it gives the error "TypeError: Object is not iterable (cannot read property Symbol(Symbol.iterator))". Removing that line , it works perfectly fine . I am not able to figure out the problem with this. Any help would be appreciated.
import { useRef } from "react";
import "./login.css";
import { loginCall } from "../../apicalls";
import { useContext } from "react";
import {AuthContext} from '../../context/AuthContext.js'
export default function Login() {
const email = useRef();
const password = useRef();
const [user,dispatch] = useContext(AuthContext);
const handleClick = (e) => {
e.preventDefault();
// loginCall(
// { email: email.current.value, password: password.current.value },
// dispatch
// );
console.log('hi');
};
// console.log(user);
return (
<div className="login">
<div className="loginWrapper">
<div className="loginLeft">
<h3 className="loginLogo">SocioFolio</h3>
<span className="loginDesc">
Connect with friends and the world around you on SocioFolio.
</span>
</div>
<div className="loginRight">
<form action=""
onSubmit={handleClick}
>
<div className="loginBox">
<input placeholder="Email" type="email" required className="loginInput" />
<input placeholder="Password" type="password" required minLength="6" className="loginInput" />
<button className="loginButton">Log In</button>
<span className="loginForgot">Forgot Password?</span>
<button className="loginRegisterButton">
Create a New Account
</button>
</div>
</form>
</div>
</div>
</div>
);
}

Node js Dropzone js - Upload file without submitting form

I am new in node js and trying to integrate single file upload using dropzone js. I want to upload image before submitting form. I have managed to call the upload action before submitting.
Here is my html code:
<form id="add_user" name="add_user" class="form-horizontal" action="/add-new-user" method="POST">
<div class="directory-bg text-center">
<div class="directory-overlay">
<span id="imageuploader">
<input name="profileimg" id="profileimg" type="hidden" value="">
<img id="ws_user_avatar" class="rounded-circle thumb-lg img-thumbnail dropzone" data-thumb="public/assets/images/users/user.png" src="public/assets/images/users/user.png" alt="Generic placeholder image">
<!--<div class="fallback">
<input name="image" id="image" type="file">
</div>-->
x
</span>
</div>
</div>
<div class="directory-content p-4">
<div class="mt-4">
<% if(success != "") {%>
<div class="alert alert-success" role="alert">
<strong>Done!</strong> <%= success %>
</div>
<% } %>
<div class="row">
<div class="col-md-12">
<div class="mb-3">
<label class="form-label" for="email">Email Address</label>
<input type="email" class="form-control" name="email" id="email" placeholder="Email Address" data-key="Email Address" autocomplete="off" autofill="false">
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label" for="fname">First Name</label>
<input type="text" class="form-control" name="fname" id="fname" placeholder="First Name" data-key="First Name" autocomplete="off" autofill="false">
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label" for="lname">Last Name</label>
<input type="text" class="form-control" id="lname" name="lname" placeholder="Last Name" data-key="Last Name" autocomplete="off" autofill="false">
</div>
</div>
</div>
</div>
</div>
</form>
Here is the js code to handle dropzone event
Dropzone.autoDiscover = false;
var myDropzone = new Dropzone(".dropzone", {
url: '/upload-image',
autoProcessQueue: false,
uploadMultiple: false,
maxFiles:2,
maxFilesize: 2,
createImageThumbnails:false,
hiddenInputContainer: "img.rounded-circle",
init: function(file) {
var prevFile = null;
this.on("addedfile", function(file) {
var $this = this;
setTimeout(function () {
if(file.status == "error"){
alert(file.previewTemplate.innerText);
} else {
if(prevFile){
$this.removeFile($this.files[0])
}
prevFile = file;
$("#user_avatar").attr('data-imgname', file.name);
previewImage($this);
}
}, 10);
});
}
});
function previewImage(input){
let fileReference = input.files && input.files[0];
if(fileReference){
var reader = new FileReader();
reader.onload = (event) => {
document.getElementById('user_avatar').src = event.target.result;
}
reader.readAsDataURL(fileReference);
}
}
$(document).on('click','#btn_submit', function(e){
e.preventDefault();
if(myDropzone.getQueuedFiles().length > 0){
myDropzone.processQueue();
} else {
$("#add_user").submit();
}
});
Here is the post handler code in router.js file:
const express = require('express');
const router = express.Router();
router.post('/upload-image', function(req, res){
console.log('requested inage',req.files.file.path);
// fs.readFile(request.files.file.path, function(err, data) {
// var newPath = __dirname + "/public/img/xspectra/customlogo.png";
// fs.writeFile(newPath, data, function (err) {
// console.log("Finished writing file..." + err);
// response.redirect("back");
// });
// });
});
When the dropzone myDropzone.processQueue() function called, I get an error message in the post handler function TypeError: Cannot read property 'file' of undefined.
Can anyone suggest me where I am doing wrong?
Many Thanks!
That means that the file uploaded didn't properly make it to your web server. Are you using express-fileupload on the nodejs side to handle the uploads?
If so, I recommend checking out this link on a really great tutorial

How to get form data as a object in reactjs

I'm trying to create a google form with react,
I have been creating all the questions as a components
if (props.type == "text") {
return (
<div className="box">
<h3 className="">{props.qustion}</h3>
<input className="short-text" placeholder="Your answer" id={"text"+props.id} name={"q"+props.id} type="text" onChange={updateField}/>
</div>
)
}
else if (props.type == "choice") {
return (
<div className="box">
<h3 className="">{props.qustion}{props.requre? <label className="requir">*</label>:""}</h3>
{props.answer.map(ans=>(
<div key={ans}>
<input className="radio" type="radio" id={ans} name={"radio"+props.id} value={ans} required={props.requre} onChange={updateField}/>
<label htmlFor={ans}>{ans}</label>
</div>
))
}
</div>
)
and I have been creating a form on the app file and put the components inside him,
return (
<div className="App">
<FormTitle/>
<form>
{
error? <h1>the sorce not found</h1>:data.map((item) =>(<Qustion qustion={item.question} type={item.type} requre={item.requre} id={item.id} answer={item.answares} key={item.id} />))
}
<div className="submit-right">
<input className="submit-button" type="submit" value="Submit" />
</div>
</form>
</div>
);
how to get all the form data as an object to create a post request ??
Try this function at start of the file where the form is
const formSubmit = (event) => {
event.preventDefault();
var data = new FormData(event.target);
let formObject = Object.fromEntries(data.entries());
console.log(formObject);
}
and in the form use this onSubmit={formSubmit}
<form onSubmit={formSubmit}>
<any element or components>
</form>
entries is not a function you can just reach it
const formSubmit = (event) => {
event.preventDefault();
var data = new FormData(event.target);
let formObject = Object.fromEntries(data.entries);
console.log(formObject);
}

Cannot read property 'heading' of null

My problem is I got an unexpected error at the browser end that says Cannot read property 'heading' of null
also marks this error at the client page file like about.ejs and showing; in the snap attached
I have provided all the required codes related to this. I reviewed multiple times to find for what or to where the actual errror originated but did not able to fix it.
codes of about.ejs
<%-include('./partials/header')%>
<div class="container-fluid">
<h1>About Section</h1>
<div class="card shadow mb-4">
<div class="card-header">
<form action="/admin/portfolio/create" method="post">
<button type="submit" class="btn btn-success">Edit About Page</button>
</form>
</div>
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">About Area</h6>
</div>
<div class="card-body">
<div class="table-responsive">
<form action="/admin/about" method="post" >
<div class="form-group">
<label for="exampleFormControlInput1">Headings:</label>
<input class="form-control" type="text" name="heading" id="exampleFormControlInput1" value="<%=about.heading%>" >
</div>
<div class="form-group">
<label for="exampleFormControlInput2">Sub-Headings:</label>
<input class="form-control" type="text" name="subheading" id="exampleFormControlInput2" value="<%=about.subheading%>" >
</div>
<div class="form-group">
<textarea id="editor1" name="content" rows="10" cols="80"><%=about.content%></textarea>
</div>
<button type="submit" class="btn btn-primary">Save & Update</button>
</form>
</div>
</div>
</div>
<%-include('./partials/footer')%>
here is my router.js file
router.get('/admin/about',serverController.isAuthenticated,serverController.about)
router.post('/admin/about',serverController.isAuthenticated,serverController.about_post)
This is also my controller file
exports.about = async function(req,res){
res.render('server/about', {
about : await aboutCollection.findOne()
})
}
exports.about_post = function(req,res){
let about = new About(req.body)
about.create().then(async()=>{
res.redirect('/admin/about')
}).catch(()=>{
res.send('404')
})
}
and finally this all about my model of about page
const aboutCollection = require('../db').db().collection('about')
const objectId = require('mongodb').ObjectID
const About = function(about){
this.about = about
}
About.prototype.create = function(){
return new Promise(async(resolve,reject)=>{
await aboutCollection.updateOne({}, {$set :
{
heading : this.about.heading,
subheading : this.about.subheading,
content : this.about.content
}
})
resolve()
})
}
module.exports = About
it's because about sent value of none at the ejs tag i mean
<%= about.heading%>
Do,
exports.about = async function(req,res){
res.render('server/about', {
about : await aboutCollection.find().toArray()
})
}
Instead of,
exports.about = async function(req,res){
res.render('server/about', {
about : await aboutCollection.findOne()
})
}
In my case, I did this; after trying then see error has gone.

Trying to display IMG with src set to Binary/Buffer image data from Mongoose

Trying to display IMGs with React/JSX with Buffered/Binary data saved to my MongoDB/Mongoose database.
i iterate over the data array with the IMG element looking like this:
<img src={`data:${item.img.contentType};base64,${item.img.data.data.toString("base64")}`} alt="" />
import React, { useState, useEffect } from "react";
import axios from "axios";
const FilesUpload = () => {
const [allPics, setAllPics] = useState([]);
useEffect(() => {
const getPics = async () => {
let res = await axios.get("http://localhost:8080/");
setAllPics(res.data);
};
// query the server for all of the picture objects
getPics();
}, []);
const [state, setState] = useState({});
const handleChange = (e) => {
e.preventDefault();
setState(e.target.value);
console.log(state);
};
return (
<>
<h1>upload an image</h1>
<hr />
<div>
<form
action="http://localhost:8080/"
method="POST"
encType="multipart/form-data"
>
<div>
<label>Image Title</label>
<input type="text" id="name" placeholder="Name" name="name" onChange={handleChange} value={state.name}/>
</div>
<div>
<label htmlFor="desc">Image Description</label>
<textarea id="desc" name="desc" rows="2" placeholder="Description"
onChange={handleChange} value={state.desc}/>
</div>
<div>
<label htmlFor="image">Upload Image</label>
<input type="file" id="image" name="image" required />
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>
</div>
{allPics.length > 0 ? (
<div>
{allPics.map((item, index) => (
<div key={index}>
<div>
<img src={`data:${item.img.contentType};base64,${item.img.data.data.toString("base64")}`} alt="" />
</div>
</div>
))}
</div>
) : (
<>
<hr />
<br />
<h1>uploaded files</h1>
<h5>Loading..</h5>
</>
)}
</>
);
};
export default FilesUpload;
but I always get ERR_INVALID_URL:
from similar threads on the net I've read that I need to take those comma-delimitated values and remove the comma which will give me the proper data. having a hard time figuring that out. any help would be great. thanks
I was facing the same problem after saving image like this in my mongoose model and after many research I resolved this, hope this works for you also
const base64String = btoa(String.fromCharCode(...new Uint8Array(item.img.data.data)));
and in img tag put this -:
src={`data:image/${item?.img?.contentType};base64,${base64String}`}

Resources