J
J
JoyRax2021-08-24 10:56:52
MongoDB
JoyRax, 2021-08-24 10:56:52

How to deal with TypeError: Cannot read property 'db' of undefined?

Hello, I am learning nodejs, mongodb and expressjs. encountered an error


C:\Users\Dmytro Dryshliuk\Documents\Projects\ilerex\models\auth.js:6
this.collection.users = this._mongo.db('users').collection('users')
------ -----------------------------------^
TypeError: Cannot read property 'db' of undefined
---at new AuthModel (C:\Users\Dmytro Dryshliuk\Documents\Projects\ilerex\models\auth.js:6:39)
---at Object. (C:\Users\Dmytro Dryshliuk\Documents\Projects\ilerex\server.js:13:19)
---at Module._compile (node:internal/modules/cjs/loader:1101:14)
---at Object .Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
---at Module.load (node:internal/modules/cjs/loader:981:32)
---at Function. Module._load (node:internal/modules/cjs/loader:822:12)
---at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:79:12)
---at node:internal/main/run_main_module:17:47


and I can't figure out why it doesn't work

./server.js
const express = require('express')
const mongodb = require("mongodb")
const cookie = require('cookie-parser')
const AuthModel = require('./models/auth.js')


const app = express()
const MongoClient = new mongodb.MongoClient('mongodb://localhost:27017/')

MongoClient.connect()
console.log(MongoClient)
console.log('======================================')
const authModel = new AuthModel(MongoClient)

app.use(express.urlencoded({extended: true}))
app.use(express.static('public'))
app.use(cookie('secret key'))

require('./routes/index')(app, authModel)
require('./routes/auth')(app, authModel)

app.listen(3000, () => {
    console.log('Server started')
})


./models/auth.js
const SHA1 = require('sha1')

class AuthModel {
  constructor (_mongo) {
    console.log(_mongo)
    this.collection.users = this._mongo.db('users').collection('users')
    this.collection.sessions = this._mongo.db('session').collection('session')
  }

  signup = async (data) => { // data = { login, password }
        await this.collection.users.insertOne({
            login: data.login,
            password: data.password,
            sids: []
        })

        return true
  }

  signin = async (data) => { // data = { login, password, user_agent }
    const cDate = this.createDate()
    const session = {}
    const user = await this.collection.users.findOne({ login: data.login })

    if (user) {
      if (user.password == data.password) {
        const sid = SHA1(user._id + cDate)

        session.sid = sid
              session.user = user._id
              session.dataCreateSession = cDate
              session.userAgent = data.user_agent

              const sids = Array.from(user.sids).push(session)

              await this.collection.sessions.insertOne(session)
              await this.collection.users.updateOne(
                {_id: user._id}, 
                {$set: {sids: sids}},
                {upsert: true}
            )

            return { is: true, sid: sid }
      }
      else { return { is: false, error: 'invalid_password' } }
    }
    else { return { is: false, error: 'invalid_login' } }
  }

  isAuth = async (data) => { // data = { sid, user_agent }
    if (data.sid) {
      const session = await this.collection.sessions.findOne({ sid: data.sid })

      if (session.userAgent == data.user_agent) { return { is: true, session: session } }
      else { return { is: false, error: 'invalid_user_agent' } }
    }
    else { return { is: false, error: 'sid_not_found' } }
  }

  createDate = () => {
        let fullDate = new Date()

        let date = fullDate.getDate()
        let month = fullDate.getMonth()
        let year = fullDate.getFullYear()
        let hours = fullDate.getHours()
        let minutes = fullDate.getMinutes()
        let seconds = fullDate.getSeconds()

        let cDate = year + "-" + month + "-" + date + " " + hours + ":" + minutes + ":" + seconds
        return cDate
    }
}

module.exports = AuthModel


./routers/auth.js
const { Router } = require('express')
const path = require('path')
const sha1 = require('sha1')

module.exports = (app, Model) => {
    const router = Router()

    router.get('/signin', async (req, res) => {
        const auth = Model.isAuth({
            sid: req.cookies.sid,
            user_agent: req.header('user-agent')
        })

        if (auth.is) { res.redirect('/') }
        else { res.sendFile(path.join(__dirname, '../public/pages/signin.html')) }
    })

    router.post('/signin', async (req, res) => {
        const result = Model.signin({
            login: req.body.login,
            password: req.body.password,
            user_agent: req.header('user-agent')
        })

        if (result.is) { res.cookie('sid', result.sid) }
        else { res.redirect(`/login?status=${result.error}`) }
        
        res.redirect('/')
    })

    router.get('/signup', async (req, res) => {
        res.sendFile(path.join(__dirname, '../public/pages/signup.html'))
    })

    router.post('/signup', async (req, res) => {
        Model.signup({
            login: req.body.login,
            password: req.body.password
        })

        res.redirect('/signin')
    })
    
    router.get('/signout', async (req, res) => {
        res.send('signout...')
    })

    app.use(router)
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
J
JoyRax, 2021-08-24
@JoyRax

I asked the question myself - I decided it myself)
Here I made a syntax error in the ./models/auth.js file

constructor (_mongo) {
    console.log(_mongo)
    this.collection.users = this._mongo.db('users').collection('users')
    this.collection.sessions = this._mongo.db('session').collection('session')
  }

I pass _mongo as an argument to the constructor and called it as a class property

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question