'Fetching data from MongoDB and displaying it in React App

I am working on creating a web app of an interactive map of campus for the school I'm attending. The web-app will allow students to click on a specific building on campus, which will bring up a map of the classrooms in that building. From there, a user can then click on a classroom which will then display a list of all classes in that room for each day of the school week. I have created my own database of all the classes offered at my school with attributes such as name, section, building, roomnum, and coursenum. I have done enough of the backend where I can connect to my database using Insonmia/Postman where I am able to filter classes based on building, room number and course section (Accounting, Biology etc.) The problem that I am running into is actually displaying the data from my database on the frontend part of my application.

Here is the backend section of my application so far...

server.js

import express from "express"
import cors from "cors"
import classes from "./api/classes.route.js"

const app = express()

app.use(cors())
app.use(express.json())

app.use("/api/v1/classes", classes)
app.use("*", (req, res) => res.status(404).json({ error: "not found"}))

export default app

index.js

import app from "./server.js"
import mongodb from "mongodb"
import dotenv from "dotenv"
import ClassesDAO from "./dao/ClassesDAO.js"

dotenv.config()
const MongoClient = mongodb.MongoClient

const port = process.env.PORT || 8000

MongoClient.connect(
  process.env.UJCLASSES_DB_URI,
  {
    maxPoolSize: 50,
    wtimeoutMS: 2500,
    useNewUrlParser: true }
  )
  .catch(err => {
    console.error(err.stack)
    process.exit(1)
  })
  .then(async client => {
    await ClassesDAO.injectDB(client)
    app.listen(port, () => {
      console.log(`listening on port ${port}`)
    })
  })

classesDAO.js

import mongodb from "mongodb"
const ObjectId = mongodb.ObjectID
let classes

export default class ClassesDAO {
  static async injectDB(conn) {
    if (classes) {
      return
    }
    try {
      classes = await conn.db(process.env.UJCLASSES_NS).collection("Classes")
    } catch (e) {
      console.error(
        `Unable to establish a collection handle in ClassesDAO: ${e}`,
      )
    }
  }

  static async getClasses({
    filters = null,
    page = 0,
    classesPerPage = 20,
  } = {}) {
    let query
    if (filters) {
      if ("name" in filters) {
        query = { $text: { $search: filters["name"] } }
      } else if ("section" in filters) {
        query = { "section": { $eq: filters["section"] } }
      } else if ("course" in filters) {
        query = { "course": { $eq: filters["course"] } }
      } else if ("room" in filters) {
        query = {"room": { $eq: filters["room"] } }
      }
    }

    let cursor
    
    try {
      cursor = await classes
        .find(query)
    } catch (e) {
      console.error(`Unable to issue find command, ${e}`)
      return { classesList: [], totalNumClasses: 0 }
    }

    const displayCursor = cursor.limit(classesPerPage).skip(classesPerPage * page)

    try {
      const classesList = await displayCursor.toArray()
      const totalNumClasses = await classes.countDocuments(query)

      return { classesList, totalNumClasses }
    } catch (e) {
      console.error(
        `Unable to convert cursor to array or problem counting documents, ${e}`,
      )
      return { classesList: [], totalNumClasses: 0 }
    }
  }
  
  static async getSections() {
    let sections = []
    try {
      sections = await classes.distinct("section")
      return sections
    } catch (e) {
      console.error(`Unable to get sections, ${e}`)
      return sections
    }
  }

  static async getBuildings() {
    let buildings = []
    try {
      buildings = await classes.distinct("building")
      return buildings
    } catch (e) {
      console.error('Unable to get buildings, ${e}')
      return buildings
    }
  }

  static async getRooms() {
    let rooms = []
    try {
      rooms = await classes.distinct("room")
      return rooms
    } catch (e) {
      console.error('Unable to get rooms, ${e}')
      return rooms
    }
  }
}

classes.controller.js

import ClassesDAO from "../dao/ClassesDAO.js"

export default class ClassesController {
  static async apiGetClasses(req, res, next) {
    const classesPerPage = req.query.classesPerPage ? parseInt(req.query.classesPerPage, 10) : 20
    const page = req.query.page ? parseInt(req.query.page, 10) : 0

    let filters = {}
    if (req.query.section) {
      filters.section = req.query.section
    } else if (req.query.course) {
      filters.course = req.query.course
    } else if (req.query.name) {
      filters.name = req.query.name
    } else if (req.query.building) {
      filters.name = req.query.building
    } else if (req.query.room) {
      filters.room = req.query.room
    }

    const { classesList, totalNumClasses } = await ClassesDAO.getClasses({
      filters,
      page,
      classesPerPage,
    })

    let response = {
      classes: classesList,
      page: page,
      filters: filters,
      entries_per_page: classesPerPage,
      total_results: totalNumClasses,
    }
    res.json(response)
  }
  
  static async apiGetClassSections(req, res, next) {
    try {
      let section = await ClassesDAO.getSections()
      res.json(section)
    } catch (e) {
      console.log(`api, ${e}`)
      res.status(500).json({ error: e })
    }
  }

  static async apiGetClassBuildings(req, res, next) {
    try {
      let building = await ClassesDAO.getBuildings()
      res.json(building)
    } catch (e) {
      console.log('api, ${e}')
      res.status(500).json({ error: e })
    }
  }

  static async apiGetClassRooms(req, res, next) {
    try{
      let room = await ClassesDAO.getRooms()
      res.json(room)
    } catch (e) {
      console.log('api, ${e}')
      res.status(500).json({ error: e })
    }
  }
}

classes.route.js

import express from "express"
import ClassesCtrl from "./classes.controller.js"

const router = express.Router()

router.route("/").get(ClassesCtrl.apiGetClasses)
router.route("/sections").get(ClassesCtrl.apiGetClassSections)
router.route("/buildings").get(ClassesCtrl.apiGetClassBuildings)
router.route("/rooms").get(ClassesCtrl.apiGetClassRooms)

export default router

I understand that this is not a platform that spits out exact answers, however that is not what I'm looking for. I have been stuck on this problem for over a week and have noticed that my project seems to be different than others. For my project, all I need to do is fetch data from an already completed database and display it. I do not need update, delete or insert functionality.

If anyone could point me in the right direction, or link any docs that could help me out I would be very grateful.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source