Home > Enterprise >  File input always shows No file chosen
File input always shows No file chosen

Time:06-06

I'm building a form using React & Nodejs & MongoDB, where you can fill the form and upload a file with some other text inputs.

However, after i submit, i receive only text inputs in my database. The chosen file (desired to upload) doesn't appear at all in the database. I am expecting to get all the data form (the uploaded file and text inputed) in my database.

I tested my backend and it works correctly (it uploads all the inputs).

Ps: In browser, when i select a file (.pdf) to upload, the file input always shows no file chosen !

Console.dev : Error

{title: 'Miss', fname: 'zaezae', lname: 'zaeazee', email: '[email protected]', phoneNumber: '12345678', …}
coverLetter: "zaez e az ezae e zae aeae  "
cv: ""
email: "[email protected]"
fname: "zaezae"
lname: "zaeazee"
myFile: "C:\\fakepath\\test.pdf"
phoneNumber: "12345678"
title: "Miss"

Formulaire.jsx:29
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'then')
at submit (Formulaire.jsx:29:1)

Backend:

server.js:

const express = require('express')
const mongoose = require('mongoose')
const bodyparser = require('body-parser')

const FormRoute = require('./routes/FormRoute')

//database
mongoose.connect('mongodb://localhost:27017/form', { useNewUrlParser: true, useUnifiedTopology: true })
const db = mongoose.connection

db.on('error', (err) => {
  console.log(err)
})
db.once('open', () => {
  console.log("Database connection established!")
})


//app
const app = express()

app.use(bodyparser.urlencoded({ extended: true }))
app.use(bodyparser.json())

//cors
const cors = require('cors')
app.use(cors())

//server run
const PORT = process.env.PORT || 5000
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
})

app.use('/api/form', FormRoute);

Axios.js:

import axios from 'axios'

export const Axios = axios.create({
    baseURL: 'http://localhost:5000',
})

Apiroutes.js:

const form = "/api/form"


export const requests = {
    formApi: {
        store: form   '/store'
    }
}

formservices.js:

import { Axios } from "../config/axios";
import { requests } from "../config/apiroutes";

export const FormService = {
    store: (data) => {
        Axios.post(requests.formApi.store, data)
            .then(res => {
                return res
            })
            .catch(err => {
                return err
            })
    }
}

formController.js :

const form = require('../models/FormModel')


const store = (req, res, next) => {
    let candidate = new form({
        title: req.body.title,
        fname: req.body.fname,
        lname: req.body.lname,
        email: req.body.email,
        phoneNumber: req.body.phoneNumber,
        coverLetter: req.body.coverLetter
    })
    if (req.file) {
        candidate.cv = req.file.path
    }
    candidate.save()
        .then(response => {
            res.json({
                success: true,
                message: 'Candidate added successfully!',
                data: candidate,
            })
        })
        .catch(error => {
            res.json({
                success: false,
                message: 'An error occured!',
                error: error,
            })
        })
}

module.exports = {
    store
}

Frontend:

Formulaire.jsx :

import React, { useState } from 'react'
import Divider from '@mui/material/Divider';
import './Formulaire.css'
import { titles } from '../../mock/titles'
import { FormService } from '../../services/formServices';


const Form = () => {
    const [storedata, setstoredata] = useState({
        title: '',
        fname: '',
        lname: '',
        email: '',
        phoneNumber: '',
        cv: '',
        coverLetter: ''
    })

    const handleChange = e => {
        const { name, value } = e.target;
        setstoredata(prevState => ({
            ...prevState,
            [name]: value
        }));
    };

    const submit = async () => {
        console.log(storedata);
        await FormService.store(storedata)
            .then(res => {
                console.log(res);
            })
            .catch(err => {
                return err
            })
    }



    return (
        <div className='container'>
            <div className='header'>
                <div className='title'>
                    <a className='quizbutton' href="/quiz">Take a Test (Quiz)</a>
                    <h1>Apply for a Position :</h1>
                </div>
            </div>
            <Divider style={{ maxWidth: '1000px', marginLeft: '250px' }} />
            <div id="content">

                <div id="formWrapper">
                    <form id="msform" method='post' action='/uploadFile' enctype="multipart/form-data">

                        <fieldset id="fieldset3">
                            <h2 >Please complete the form below for a position with us.</h2>
                            <h3 >Reference 0001</h3>
                            {/* <div ></div> */}

                            <div >
                                <label for="title">Title :</label>
                                <select name="title" value={storedata.title} onChange={handleChange}>
                                    <option hidden></option>
                                    {
                                        titles.map((c, i) => {
                                            return (
                                                <option key={i} value={c}>{c}</option>
                                            )

                                        })
                                    }
                                </select>

                                <label for="fname">First Name<span>*</span> :</label>
                                <input type="text" name="fname" value={storedata.fname} onChange={handleChange} id="fname" placeholder="Please enter your first name" required />

                                <label for="lname">Last Name<span>*</span> :</label>
                                <input type="text" name="lname" value={storedata.lname} onChange={handleChange} id="lname" placeholder="Please enter your last name" required />

                                <label for="email">Email<span>*</span> :</label>
                                <input type="email" name="email" value={storedata.email} onChange={handleChange} id="email" placeholder="Please enter your email" required />

                                <label for="phoneNumber">Phone N° :</label>
                                <input type="number" name="phoneNumber" value={storedata.phoneNumber} onChange={handleChange} id="phoneNumber" placeholder="Phone number" />

                                <label for="CV">Upload CV <span>*</span>:</label>
                                <input type="file" name="myFile" id="cv" value={storedata.cv} onChange={handleChange} accept="application/msword, application/pdf" placeholder="Cover Letter" required />

                                <label for="coverLetter">Cover Letter :</label>
                                <textarea type="text" name="coverLetter" value={storedata.coverLetter} onChange={handleChange} id="coverLetter" placeholder="cover Letter" />
                            </div>

                            <br />
                            <input type="submit" name="submit"  value="Submit" onClick={submit} />
                        </fieldset>

                    </form>

                </div>
            </div>
        </div>
    )
}

export default Form

CodePudding user response:

The error is because you are not waiting to axios to respond. You have to return a promise here:

export const FormService = {
    store: (data) => {
       return new Promise((resolve, reject) => {
          Axios.post(requests.formApi.store, data)
            .then(res => {
                resolve(res);
            })
            .catch(err => {
                reject(err)
            })
       }
        
    }
}

Or you can use async await if you prefer.

The thing that i dont understand is if you are trying to send the file or just its name. If you want to upload the file you have to send the event.target.files (like this: https://www.geeksforgeeks.org/file-uploading-in-react-js/) And use a middleware like express-fileupload or multer in the server.

CodePudding user response:

I fixed my problem by changing name="myFile" id="cv" to name="cv" id="cv"

  • Related