0

I am trying to populate MongoDB data to html select option.

This is what I have done so far

  1. I have created a database books and created collection AuthorDB

  2. I manually inserted data (to check if it really is working)

  3. But when I used postman to get data, I get an empty array means no data. (But I have inserted data to AuthorDB collection)

Here is my server.js

const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');

const BookDB = require('./book-dbmodel');
const AuthorDB = require('./author-dbmodel');

const app = express();
const router = express.Router();

app.use(bodyParser.json());
app.use(cors());
app.use('/books', router);

//connect to books database
mongoose.connect('mongodb://127.0.0.1:27017/books', {useNewUrlParser: true});

const connection = mongoose.connection;
connection.once('open', () => {
    console.log("Connected to MongoDB via port 27017");
});

app.listen(4000, () => {
    console.log('Listening to port 4000');
});

// add book http://localhost:4000/books/add
router.route('/add').post((req, res) => {
    let bookDB = new BookDB(req.body);
    bookDB.save().then((bookDB) => {
        res.status(200).send(`${bookDB} Added!`);
    }).catch((err) => {
        res.status(400).send({message: err});
    });
});


//get all authors http://localhost:4000/books/authors
router.route('/authors').get((req, res) => {
    AuthorDB.find((err, authors) => {
        if(err) throw err;
        res.status(200).send(authors);
    });
});

//get books by author name http://localhost:4000/books/authors/authorName
router.route('/authors/authorName').get((req, res) => {
    let authorName = req.params.authorName;
    BookDB.find({firstName: {$regex: `${authorName}`, $options: "i"}}, (err, books) => {
        if(err) throw err;
        res.status(200).send(books);
    });
});

And this is my App.js in front-end:

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

const ShowAuthors = (props) => (
    <option value={props.author.firstName}>{props.author.firstName}</option>
);
export default class AddBooks extends Component{

    constructor(props){
        super(props);

        this.state = {
            authorArray: [],
            name: '',
            isbn: 0,
            author: '',
            price: 0,
            yearOfPublication: 0,
            publisher: ''
        }
    }



    //to get author list on dropdown select
    componentDidMount(){
        axios.get('http://localhost:4000/books/authors/')
        .then(authors => {
            console.log(authors.data);
            this.setState({
                authorArray: authors.data
            });
        }).catch(err => {
            console.log(err);
        });
    }

    getAuthors(){   
        return this.state.authorArray.map((currentAuthor, id) => {
            return <ShowAuthors author={currentAuthor} key={id} />
        });
    }

    onSubmit(){

    }
    onChangeName(){

    }
    onChangeISBN(){

    }

    render(){
        return(
            <div className="container">
                <h1>Add Books</h1>

                <form onSubmit={this.onSubmit}>

                <div className="form-group">
                    <label htmlFor="book-name">Book Name</label>
                    <input
                    value={this.state.name} 
                    onChange={this.onChangeName}
                    type="text" className="form-control" id="book-name" aria-describedby="emailHelp" placeholder="Book Name"/>                    
                </div>

                <div className="form-group">
                    <label htmlFor="book-isbn">ISBN</label>
                    <input
                    value={this.state.isbn} 
                    onChange={this.onChangeISBN}
                    type="number" className="form-control" id="book-isbn" aria-describedby="emailHelp" placeholder="ISBN"/>                    
                </div>


                <div className="form-group">
                    <label htmlFor="author-name">Authors</label>
                    <select

                    className="form-control" name="authors" id="authors">
                        {this.getAuthors()} {/* this doesn't return anything but an empty array */}
                    </select>
                </div>

                <div className="form-group">
                    <label htmlFor="book-price">Book Price</label>
                    <input type="number" className="form-control" id="book-price" name="book-price" aria-describedby="emailHelp" placeholder="Book Price"/>                    
                </div>

                <div className="form-group">
                    <label htmlFor="book-year">Published Year</label>
                    <input type="number" className="form-control" id="book-year" name="book-year" aria-describedby="emailHelp" placeholder="Year"/>                    
                </div>                

                <div className="form-group">
                    <label htmlFor="book-publisher">Book Publisher</label>
                    <input type="number" className="form-control" id="book-publisher" name="book-publisher" aria-describedby="emailHelp" placeholder="Publisher"/>                    
                </div>


                </form>
            </div>
        );
    }
}

And this is my mongodb visualization:

DB

And this is my AuthorDB schema model:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

let AuthorDB = new Schema({
    firstName: {type: String},
    lastName: {type: String},
    nationality: {type: String}
});

module.exports = mongoose.model('AuthorDB', AuthorDB);

1 Answer 1

1

for mongoose.model() method

The first argument is the singular name of the collection your model is for. Mongoose automatically looks for the plural, lowercased version of your model name. Thus, for the example above, the model Tank is for the tanks collection in the database.

Mongoose trying to be smart and detect the model name, but you can force it to use the collection you want like this:

new Schema({..}, { collection: 'AuthorDB' })

Or when you create the model, like this:

module.exports = mongoose.model('AuthorDB', AuthorDB, 'AuthorDB')

Also you're trying to access this parameter req.params.authorName while it not defined in your route, you're missing : in your route.

router.route('/authors/authorName')

It should be like this:

router.route('/authors/:authorName')

to be able to get the authorName value.

Sign up to request clarification or add additional context in comments.

4 Comments

I am not trying access router.route('/authors/:authorName'). I am tryin to access router.route('/authors')
can you post you AuthorDB file, I think there is the problem.
Done :) Can you please look into this?
You just saved me :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.