Fetching json data from MongoDB returns an empty array instead of actual data

45 Views Asked by At

I am using a connection string to connect to a MongoDB database named myflixDB2. I am encountering an issue fetching data from the database. There is clearly data inside my MongoDB, but for some reason an empty array is always returned, as if the collection is empty.

I was expecting to fetch a list of movie titles into my main-view component for my single-page-application. I have checked my connection string and even created a second database, tried interacting with that one instead, still no luck. I have been dealing with this problem for longer than I would like to admit. Am I missing something? Any help would be appreciated!

models.js

const mongoose = require("mongoose");
const bcrypt = require('bcrypt');

let movieSchema = mongoose.Schema({
  Title: {type: String, required: true},
  Description: {type: String, required: true},
  Genre: {
    Name: String,
    Description: String
  },
  Director: {
    Name: String,
    Bio: String
  },
  Actors: [String],
  ImagePath: String,
  Featured: Boolean
});

let userSchema = mongoose.Schema({
  Username: {type: String, required: true},
  Password: {type: String, required: true},
  Email: {type: String, required: true},
  Birthday: Date,
  FavoriteMovies: [{ type: mongoose.Schema.Types.ObjectId, ref: "Movie" }]
});

userSchema.statics.hashPassword = (password) => {
  return bcrypt.hashSync(password, 10);
};

userSchema.methods.validatePassword = function(password) {
  return bcrypt.compareSync(password, this.Password);
};

let Movie = mongoose.model("movies", movieSchema);
let User = mongoose.model("user", userSchema);
let Users = mongoose.model("users", userSchema); // Add this line

module.exports = {
  Movie,
  User,
  Users, // Add this line
};

index.js

const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const cors = require('cors');
const Models = require('./models.js');
const { Movie } = Models;

const mongoURI = 'mongodb+srv://username:[email protected]/myflixDB2?retryWrites=true&w=majority&appName=Cluster0';

// Connect to MongoDB with error handling
mongoose.connect(mongoURI, { useNewUrlParser: true, useUnifiedTopology: true })
  .then(() => console.log('MongoDB connected'))
  .catch(err => console.error('MongoDB connection error:', err));

const app = express();

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

app.use(cors({
    origin: 'http://localhost:63239'
}));

// Define routes
app.get('/', (req, res) => {
    res.send('Welcome to the best movie search app ever! (Maybe)');
});

app.get('/movies', async (req, res) => {
    try {
        const movies = await Movie.find();
        console.log('Fetched movies:', movies); // Logging fetched movies
        res.json(movies);
    } catch (err) {
        console.error(err);
        res.status(500).json({ error: 'Internal Server Error' });
    }
});

// Add more routes as needed

const port = process.env.PORT || 8080;
app.listen(port, '0.0.0.0', () => {
    console.log('Listening on Port ' + port);
});
1

There are 1 best solutions below

0
jQueeny On

As per the docs, when you create a schema it is best practice to use the new keyword to create a new instance of the Schema class. Update your schema like so:

const movieSchema = new mongoose.Schema({
  Title: {type: String, required: true},
  Description: {type: String, required: true},
  Genre: {
    Name: String,
    Description: String
  },
  Director: {
    Name: String,
    Bio: String
  },
  Actors: [String],
  ImagePath: String,
  Featured: Boolean
});

Then when you compile the model you need to ensure that the first argument to the mongoose.model() method is a singular version of the collection name because mongoose uses that to infer the collection name:

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.

Update like so:

const Movie = mongoose.model("Movie", movieSchema); 
// This will look for a collection called 'movies' because 'Movie' -> 'movies'