-1

It is so frustrating that over hundreds of tutorials, there isn't a single tutorial that handles file input with multiple text input and send request to server. I am trying to send post request to server with the help of axios, all the other inputs are parsed fine, however the moment i add file to it, it gives 500 error with following message "TypeError: Cannot read property 'image' of undefined" Here are the files Post.js

    import React,{Component, useState} from 'react';
    import './post.css';
    import axios from 'axios';

    class post extends Component{
       constructor(props){
    
           super(props)
           this.state={
               title:null,
               content:null,
               slug:null,
               _authorID:null,
           }
    
       }
       postHandler=(event)=>{
        this.setState({[event.target.name]:event.target.value})
       }
       imageHandler=(event)=>{
           this.setState({[event.target.files[0]]:event.target.value})
       }
    
       submitHandler=(event)=>{
           var req=new FormData()
           req.append('title',this.state.title)
           req.append('content',this.state.content)
           req.append('slug',this.state.slug)
           req.append('_authorID',this.state._authorID)
           req.append('image',this.state.image.files[0])
           console.log("e")
           event.preventDefault()
           axios(
               {url:"http://localhost:3000/post/new",
               method:'post',
               data:req});
       }
        render(){
            const {title,content,slug,_authorID,image}=this.state;
            return (<div className="container">
                <form onSubmit={this.submitHandler} method="POST">
                    <div className="form-group">
                    <label htmlFor="title">Title</label>
                    <input type="text" class="form-control" value={title} onChange={this.postHandler} name="title" placeholder="Enter title"></input>
                    </div>
                    <div className="form-group">
                    <label htmlFor="content">Content</label>
                    <input type="text" id='con' class="form-control" onChange={this.postHandler} value={content}name="content" placeholder="Enter content" size="50"></input>
                    </div>
                    <div className="form-group">
                    <label htmlFor="slug">Slug</label>
                    <input type="text" class="form-control" onChange={this.postHandler} value={slug} name="slug" placeholder="Enter slug" size="50"></input>
                    </div>
                    <div className="form-group">
                    <label htmlFor="authorID">AuthorID</label>
                    <input type="text" class="form-control" onChange={this.postHandler} value={_authorID} name="_authorID" placeholder="Enter authorID" size="50"></input>
                    </div>
                    <input type="file" name={image} value={image} onChange={this.imageHandler}></input>
                    <button className="btn btn-primary" type="submit">Submit</button>
                </form>
            </div>
            );}
    }
    export default post

App.js

    const express=require('express');
    const app=express();
    const mongoose=require('./dbConfig');
    const author=require('./schemas/AuthorSchema');
    const post=require('./schemas/PostSchema');
    const multer=require('multer');
    var path = require('path')
    app.use(express.json())
    app.use(function(req, res, next) {
        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Methods", "GET,POST,HEAD,OPTIONS,PUT,PATCH,DELETE");
        res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        next();
    });
    const storage = multer.diskStorage({
        destination: (req, file, cb) => {
          cb(null, '../public/uploads/images')
        },
        filename: (req, file, cb) => {
          cb(null, file.fieldname + '-' + Date.now()+ path.extname(file.originalname))
        }
    });
    const upload=multer({storage:storage});
    
    
    app.listen(3000,()=>{
        console.log("Server started at 3000")
    });
    app.get('/post',(req,res)=>{
        post.find({})
        .then(post => res.send(post))
        .catch((error) => console.log(error))
    })
    app.get('/post/:id',(req,res)=>{
        post.find({'_authorID':req.params.id})
        .then(post => res.send(post))
        .catch((error) => console.log(error))
    })
    app.post('/post/new',upload.single('image'),(req,res)=>{
        
        new post({'title':req.body.title,'content':req.body.content,'slug':req.body.slug,'_authorID':req.body._authorID,'date':Date.now,'image':'./public/uploads/images/'+req.file.image})
        .save()
        
        .then((post) => console.log(post))
        .catch((error) => console.log(error))
        console.log(post._authorID)
        res.send("Post Added Successfully")
    })
    app.post('/author',upload.single('photo'),(req,res)=>{
        new author({'name':req.body.name,'photo':'public/uploads/images/'+req.file.filename,'bio':req.body.bio,'username':req.body.username,'password':req.body.password,'email':req.body.email})
        .save()
        .then((author) => console.log(author))
        .catch((error) => console.log(error))
        res.send("Post Added Successfully")
    })
    app.delete('/post/delete/:id',(req,res)=>{
        console.log(req.params.id)
        post.findByIdAndDelete(req.params.id,function(err,docs){
            if(err){
            console.log(err);
            }
            else{
                console.log("Deleted"+docs);
                res.send("Deleted Successfully");
            }
        }  
    )})
    app.patch('/post/update/:id',(req,res)=>{
        post.findByIdAndUpdate(req.params.id,{'title':req.body.title,'content':req.body.content,'slug':req.body.slug,'_author':req.body._author},function(err,docs){
            if(err){
                console.log(err);
            }
            else{
                console.log("Updated Successfully");
            }
        })
    })
Marik Ishtar
  • 2,899
  • 1
  • 13
  • 27
  • 1
    I think @MarikIshtar means the stack trace as there are a number of locations in the code that have `image` referenced. – Michael Hobbs Dec 05 '20 at 22:20
  • I have written it in the title "TypeError: Cannot read property 'image' of undefined" – Owais Orakzai Dec 05 '20 at 22:21
  • We need to STACK TRACE without it we cant tell which image you error is referring to. See: https://stackoverflow.com/questions/3988788/what-is-a-stack-trace-and-how-can-i-use-it-to-debug-my-application-errors – Michael Hobbs Dec 05 '20 at 22:26

1 Answers1

0

I think your problem is here.

This...

       imageHandler=(event)=>{
           this.setState({[event.target.files[0]]: event.target.value})
       }

Should be something like...

       imageHandler=(event)=>{
           this.setState({image: event.target.value})
       }

You are trying to reference this.state.image which does not appear to have been set.

req.append('image',this.state.image.files[0])
Michael Hobbs
  • 1,663
  • 1
  • 15
  • 26