1

I am following the fullstackopen.com course and I seem to have an issue with my .env file, currently when I try to connect to the database I get this error:

error connecting to MongoDB The `uri` parameter to `openUri()` 
must be a string, got "undefined". Make sure the first parameter to 
`mongoose.connect()` or `mongoose.createConnection()` is a string.

I have figured out the process.env variable is not being read properly by Node.js from checking previous answers most of the issue has been around not having dotenv imported correctly my code has this so I don't think this could be the issue. I have also printed the .env variable to console and it is undefined. My .env file is also in the root of the project so I don't think it is that either.

I have included my .env file and the files being used to call the code below.

.env file

MONGODB_URI='mongodb+srv://fullstackopen:<MyPasswordisHERE>@cluster0.brwcy.mongodb.net/myFirstDatabase?retryWrites=true&w=majority'
PORT=3001

note.js application

require('dotenv').config()
const mongoose = require('mongoose')
const url = process.env.MONGODB_URI
console.log('connecting to', url)

mongoose.connect(url)
    .then(result => {
        console.log('connected to MongoDB')
    })
    .catch((error) => {
        console.log('error connecting to MongoDB', error.message)
    })

const noteSchema = new mongoose.Schema({
    content: String,
    date: Date,
    important: Boolean,
})

noteSchema.set('toJSON', {
    transform: (document, returnedObject) => {
        returnedObject.id = returnedObject._id.toString()
        delete returnedObject._id
        delete returnedObject.__v
    }
  })
  
module.exports = mongoose.model('Note', noteSchema)

index.js

require('dotenv').config()
const { request, application, response } = require('express')
const express = require('express')
const app = express()
const Note = require('./models/note')
app.use(express.json())
app.use(express.static('build'))


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


  app.get('/', (request, response) => {
    response.send('<h1>Hello World</h1>')
  })

  app.get('/api/notes/:id', (request, response) => {
      const id = Number(request.params.id)
      const note = notes.find(note => note.id === id)
      if(note){
        response.json(note)
      }
      else {
        response.status(404).end()
      }
    })

  app.get('/api/notes',(request, response) => {
      Note.find({}).then(notes => {
        console.log(response)
        response.json(notes)
      })
  })

  app.delete('/api/notes/:id', (request, response) => {
    const id = Number(request.params.id)
    notes = notes.filter( note => note.id !== id)

    response.status(204).end()
  })

  const generateId = () => {
    const maxId = notes.length > 0 
    ? Math.max(...notes.map(n => n.id))
    : 0

    return maxId + 1
  }

  app.post('/api/notes', (request, response) => {
   
    const body = request.body

    if(!body.content){
      return response.status(400).json({
        error: 'content missing'
      })
    }

    const note = {
      content: body.content,
      important: body.important || false,
      date: new Date(),
      id: generateId(),
    }
    
    notes = notes.concat(note)
    response.json(note)


  })

  const unknownEndpoint = (request, response) => {
    response.status(404).send({error: 'unknown endpoint'})
  }

  app.use(unknownEndpoint)

  const PORT = process.env.PORT
  app.listen(PORT, ()=> {
      console.log(`Sever is running on port ${PORT}`)
  })


I know that I have dotenv being imported in note.js and index.js, the reason for this is when I was testing why the .env was't being recognised I checked the note.js file by running that only using the command below, however in production the import is only in index.js so that isn't the issue

node note.js

My file structure for the project is also included below

.  ..  build  .env  .git  .gitignore  index.js  models  mongo.js  node_modules  package.json  package-lock.json  Procfile  requests

ARDev
  • 11
  • 1
  • 3

3 Answers3

3

Make sure that your .env is within the folder structure. E.g if your .env is on the root folder but you are trying to load it from within a folder make sure you add the correct path:

require('dotenv').config({path: __dirname + '/.env' })
ConfusedDev
  • 83
  • 1
  • 5
  • I did try this but wouldn't it still work for the index.js anyway because .env and the index.js are both in the root. Slightly stupid question here but is __dirname just a placeholder ? – ARDev Dec 20 '21 at 14:47
  • Do you have all of those files within the root folder? If index.js is in the root, you don't need to specify the path given that the .env is there. – ConfusedDev Dec 20 '21 at 14:51
  • yes all of them are in root.. – ARDev Dec 20 '21 at 14:52
  • strange. try to remove the ' from env after = e.g MONGODB_URI=mongodb+srv://fullstackopen:@cluster0.brwcy.mongodb.net/myFirstDatabase?retryWrites=true&w=majority. – ConfusedDev Dec 20 '21 at 15:00
  • still not working. – ARDev Dec 20 '21 at 15:15
  • the only thing left i can think of is to check wether there's an issue with your node version. Otherwise, this link may help: https://stackoverflow.com/questions/26973484/how-do-i-setup-the-dotenv-file-in-node-js – ConfusedDev Dec 20 '21 at 15:29
  • Yep I tried everything in that post but still didn't work. – ARDev Dec 20 '21 at 16:11
  • are you running this on a server or locally? – ConfusedDev Dec 20 '21 at 16:22
  • so I just ran it locally and it worked but for the server it is not working I am getting a 503 error. The call I am making using react seems fine but not sure. – ARDev Dec 20 '21 at 16:32
  • then it seems that it is something to do with your server or server connection. 500 messages usually correspond to internal server issues. – ConfusedDev Dec 21 '21 at 16:52
  • Yeh exactly that is the problem node can't connect to the backend via .env . When I connect to the backend with the connectiong hardcoded it works. – ARDev Dec 22 '21 at 17:11
0

Figured out the issue, when deploying with heroku you must configure the config vars to match the environment variables in .env

The other answers in StackOverflow aren't so clear on how to do this, I have outlined the steps I took below.

  1. Go to Application > Settings > Reveal config vars
  2. you will be presented with two text fields one labelled key and the other value
  3. For the key make it equal the name of your environment variable for me it was MONGODB_URI
  4. For the value field it should equal whatever you need your environment variable to be, for me it was the url for MongoDB Atlas.
ARDev
  • 11
  • 1
  • 3
0

As shown by @ConfusedDev

Add this line to your app.js

require('dotenv').config({path: __dirname + '/.env' })
Rehab
  • 26
  • 5