Aanyu Deborah O
Aanyu Deborah O

Reputation: 39

Storing select option input value in React component inside MongoDB - MERN fail. Stores it as empty string

I am working with MERN and trying to store select option input values in my MongoDb database using mongoose. Like this

import React, {Component} from 'react';
import axios from 'axios';

class Admin extends Component {
    constructor(props) {
        super(props)

        //setting initial states
        this.state= {
            college: ''
        }
    }

onChangeCollege=(event)=>{
        this.setState({college: event.target.value})
    }

 onSubmit =(event) =>{
        event.preventDefault()

        console.log('Form Submitted')

        const newCourse = {
            college:this.state.college
        }

        axios.post('http://localhost:8000/courses/admin', newCourse)
            .then(response => console.log(response.data))
            .catch(() => console.log('Error creating new course'))

        this.setState({
            college: ''
                    })
    }

   

    render(){
        
    return (
        <div className="space3">
            <h3>Add a Course to the Database</h3>
        <form autoComplete="on" onSubmit={this.onSubmit} className="space"> 
            <div className="form-group">
                 <label htmlFor="exampleInputEmail1">COLLEGE</label>
                     <select className="custom-select" id="inputGroupSelect01" >
                        <option defaultValue>Choose...</option>
                        <option value={this.state.college} onChange={this.onChangeCollege} > College of 
 Agricultural and Environmental Sciences </option>
                        <option value={this.state.college} onChange={this.onChangeCollege} > College of Humanities and Social Sciences </option>
                        <option value={this.state.college} onChange={this.onChangeCollege} > College of Education and External Studies </option>
                        <option value={this.state.college} onChange={this.onChangeCollege} > College of Health Sciences </option>
                        <option value={this.state.college} onChange={this.onChangeCollege} > College of Natural Sciences </option>
                        <option value={this.state.college} onChange={this.onChangeCollege} > College of Business and Management Studies </option>
                        <option value={this.state.college} onChange={this.onChangeCollege} > College of Engineering, Design,  Art and Technology </option>
                        <option value={this.state.college} onChange={this.onChangeCollege} > College of Veterinary Medicine, Animal Resources and Bio-Security </option>
                        <option value={this.state.college} onChange={this.onChangeCollege} > School of Law </option>
                    </select>
 </div>
<button type="submit" className="btn btn-primary">Submit</button>

            </form>
            </div>
    )
    }
}

export default Admin;

my backend is Nodejs which looks like this. THE MODEL

const mongoose = require('mongoose')

const Courses = new mongoose.Schema({
    college: {
        type:String
    }  
})

module.exports = mongoose.model('coursesmodel', Courses)

THE API

const express = require ('express')
const router = express.Router()
const coursedb = require('../models/coursedb')

//add new todo to list
router.post('/admin', (request, response) => {
    const list = new coursedb({
        college: request.body.college
    })

    list.save()
    .then(courses => {response.json(courses)})
    .catch(error => {response.json(error)})
})
 
module.exports = router

As you can see in my console, that last console.log returns an empty string for the COLLEGE value.

As you can see in my console, that last console.log returns an empty string for the COLLEGE value.

And this is what it looks like in my MongoDB.

And this is what it looks like in my MongoDB.

How do i store that COLLEGE input select option in my db as a String, like the rest, and not an empty String. Need help!

Upvotes: 1

Views: 1555

Answers (1)

Yousaf
Yousaf

Reputation: 29314

In the state, college is an empty string and in the JSX code, value of each options is this.state.college, i.e. an empty string and this is where your problem is.

Whenever onChangeCollege() is triggered, event.target.value is the value of the value attribute of the option element that triggered the onChange event, and in your case, it is this.state.college, i.e. an empty string and that is what you are sending to the server when form is submitted.

value attribute of the option element should be equal to the value of the option that is visible to the user. For example, you need to change

<option
  value={this.state.college}
  onChange={this.onChangeCollege}
>
  College of Humanities and Social Sciences
</option>

to

<option
  value="College of Humanities and Social Sciences"
  onChange={this.onChangeCollege}
>
  College of Humanities and Social Sciences
</option>

You need to do this for all of the option elements.


Side note: You don't need to add a separate onChange listener on each option, adding onChange event listener on the select element will achieve the same result.

<select
  className="custom-select"
  id="inputGroupSelect01"
  onChange={this.onChangeCollege} 
>
  ...
</select>

If you want to know why this works, see: MDN - Event Bubbling

Upvotes: 2

Related Questions