0

I am creating a MERN magazine web application that shows users articles that are stored in a mongodb. I have multiple databases, called userDB and articleDB on Mongo Atlas. These databases are located in a single cluster. The problem is, in one of my controllers, articleController.js, the find method on the collection is always returning an empty array. This results in my app breaking as it always worked and did not return an empty array, but rather, an array of three of the latest article objects before it I started transitioning my data to Atlas from my local mongodb.

This is a code snippet of my articleControllers.js:

const express = require('express');
const app = express();
const cors = require("cors");
let articleSchema = require('../models/article.model');
const mongoose = require("mongoose");

const conn = mongoose.createConnection("mongodb+srv://<username>:<password>@cluster0.c94ps.mongodb.net/articleDB?retryWrites=true&w=majority", { useNewUrlParser: true, useUnifiedTopology: true, dbName: "articleDB" });

const Article = conn.model('article', articleSchema); // update: this is where the problem was.
const fs = require("fs");
const path = require("path");

app.use(cors({
    origin: 'http://localhost:3000',
    credentials: true 
}));

app.use('/images', express.static(path.join(__dirname, '/images')));

exports.article_home_section_display_get = (req, res) => {
    const id = req.params.id;
    const firstLetter = id.charAt(0).toUpperCase();
    const restOfWord = id.substring(1, id.length);
    const fullWord = firstLetter + restOfWord;
    Article.find({article_section: fullWord}).sort({article_date: -1}).limit(3)
        .then(articles => {
            console.log(articles); //empty array
            console.log(`Found and sent over three of the latest ${fullWord} articles.`);
            res.send(articles);
        })
        .catch(err => {
            console.log(err);
        });
};

where username and password in angle brackets are my actual username and password.

Could it be that it's actually impossible to connect to mongo Atlas using mongoose.createConnection when connecting to multiple databases? Or maybe, my application is not connected to the Atlas at all because of some kind of an error that I overlooked? By the way, database on Atlas is called, articleDB, and the collection inside is article.

I have been struggling on this for a long time and cannot figure out what went wrong when I did what other people did. So, any help would be greatly appreciated.

Stacking_Flow
  • 115
  • 1
  • 1
  • 11

2 Answers2

0

put the mongoose.connect in the app.js file not in controller, and do like this

const dbURI = "mongodb+srv://<username>:<password>@cluster0.c94ps.mongodb.net/articleDB?retryWrites=true&w=majority";
mongoose.connect(dbURI,{useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false}).then((result) => {
  console.log('connected to db')
}).catch((err) => console.log(err));

create a artilce.js file and export the model like this:

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

const articleSchema = new Schema({

});

const Article= mongoose.model('article', articleSchema);
module.exports = Article;

in the controller require the article

const Article = require('./models/article'); // path of article.js file
Mohammad Yaser Ahmadi
  • 4,664
  • 3
  • 17
  • 39
0

Okay, so after a day of searching, I finally found the answer. The problem lies in:

const Article = conn.model("article", articleSchema);

which is incorrect as the first parameter, "article", is the input denoting the name of the collection inside the database. That means that Mongoose will look for the collection called articles. This is because Mongoose converts this first parameter into a plural (and lowercase if you write something like "Article"), when looking for the collection.

However, my database is called articleDB, and my collection inside this database is called article (a collection name that is not a plural!). So when Mongoose converts the first parameter "article" into articles when looking for the collection in my database, it won't be able to find it. Thus, resulting in res.data returning an empty array.

To solve this, you can add a third parameter in the .model function. Like this, which solved my problem:

const Article = conn.model("article", articleSchema, "article");

where the third parameter "article" lets Mongoose know that it should not pluralize (and convert to lowercase) the first parameter. But rather, the third parameter lets Mongoose know the explicit name of the collection.

In terms of what the first parameter does in the case where there are three parameters, I'm not really sure. But the first parameter seems redundant once you explicitly define the name of the collection in your database. It probably acts like a placeholder to differentiate between two-parameter and three-parameter .model functions.

Stacking_Flow
  • 115
  • 1
  • 1
  • 11