Hi,Im currently learning backend, and I had this error when I try to add a review using the curl command: curl -X POST ://localhost:4444/api/v1/reviews/new -H “Content-Type:application/json” -d ‘{“movieId”:12,”user”:”sara”,”review”:”good”}’, this error appears to me:TypeError: Cannot read properties of undefined (reading ‘insertOne’), i have installed all the nessury models in package.json ,also these are the project files, i gusse there is a proplem connecting ReviewsDAO with the database.
reviewsDAO.js:
import mongodb from 'mongodb';
//so we can send and receive inputs using id
const ObjectID=mongodb.ObjectId;
let reviews;
export default class ReviewsDAO{
//conn => the connection from the movieDB file
static async injectDB(conn){
//if there is a db connection don't do anything
if(reviews){
return
}
//if thee is not a db connection create a connection using try
try{
//this is from the mongoDb collections command we tried to accuses the reviews db then to the collection reviews
reviews = await conn.db("reviews").collection("reviews");
} catch(e){
console.error(`Unable to establish collection handles in userDAO: ${e}..`);
};
};
//to insert a review to a collection
static async addReview(movieId,user,review){
try{
// all of this is a key value
const reviewDoc={
movieId:movieId,
user:user,
review:review
}
//we try to insert a doc to the collection reviews
return await reviews.insertOne(reviewDoc);
}catch(e){
console.error(`Unable to post review: ${e}`);
return{error:e};
};
};
//we pass the review id to get the review from the db
static async getReview(reviewId){
try{
return await reviews.findOne({_id:ObjectID(reviewId)})
}catch(e){
console.error(`Unable to get review: ${e}`);
return{error:e};
};
};
//to update the review
static async updateReview(reviewId,user,review){
try{
//to update the review we first add the Id then update it by adding the review and the user
const updateResponse=await review.updateOne({_id:ObjectID(reviewId)},
//$set is a command from mongoDb to update something on the db
{$set:{user:user,review:review}});
return updateResponse;
}catch(e){
console.error(`Unable to update review: ${e}`);
return{error:e};
};
};
//get movies by id
static async getReviewByMovieId(movieId){
//if we want to find a movie we first add the movie id then store it into the cursor then convert the courser to an array
try{
//the movieId is a string value but we convert it by using parseInt function from javascript
const cursor=await reviews.find({movieId: parseInt(movieId)});
//convert the int value in cursor to an array
return cursor.toArray();
}catch(e){
console.error(`Unable to get review: ${e}`);
return{error:e};
};
};
};
reviews.controller.js:
//this file is to get info from the route then doing something with the info
import ReviewsDAO from "../dao/reviewsDAO.js";
//export the class reviewsController to other files
export default class ReviewsController{
//we create apiPostReviews as static so we can call it directly from reviewsController without an instance in other files
//we used async so we can waite for something to happened
static async apiPostReview(req,res,next){
try{
//get the movie id and the review and the user
const movieId = parseInt(req.body.movieId)
const review=req.body.review;
const user=req.body.user;
console.log('movieId', movieId)
//wait for the respond
const reviewResponse=await ReviewsDAO.addReview(
movieId,
user,
review
);
//add the review to the json
res.json({status:'success'});
//if there was an error this will appear
}catch(e){
res.status(500).json({error:e.message});
};
};
//
static async apiGetReviews(req,res,next){
try{
//to get the id of the review
let id=req.params.id||{};
//stor the id in review
let review=await ReviewsDAO.getReview(id);
//if there is no reviews
if(!review){
res.status(404).json({error:"Not Found"});
return
};
//respond with the review
res.json(review)
}catch(e){
console.log(`ipa ${e}`);
res.status(500).json({error:e});
};
};
//updating the review
static async apiUpdateReview(req,res,next){
try{
const reviewId=req.params.id;
const review=req.body.review;
const user=req.body.user;
const reviewResponse=await ReviewsDAO.UpdateReview(
reviewId,
review,
user
);
var{error}=reviewResponse;
//first way to say if there was an error
if(error){
res.status(500).json({error});
};
//second way
if(reviewResponse.modifiedCount===0){
throw new Error(
'Unable to update reviews'
);
};
res.json({status:"success"});
}catch(e){
res.status(500).json({error:e.message});
};
};
//delete the review
static async apiDeleteReview(req,res,next){
try{
const reviewId=req.params.id;
const reviewResponse = await ReviewsDAO.deleteReview(reviewId)
res.json({status:"success"});
}catch(e){
res.status(500).json({error:e.message});
};
};
//to get all the reviews to a specific movie
static async getReviewByMovie(req,res,next){
try{
let id = req.params.id ||{}
let reviews= await ReviewsDAO.getReviewByMovie(id)
if(!reviews){
res.status(404).json({error:"Not Found"});
return
}
res.json(reviews)
}catch(e){
console.log(`ipa ${e}`);
res.status(500).json({error:e.message});
};
};
};
reviews.route.js:
import express from 'express';
import ReviewsController from "./reviews.controller.js";
// const router = require('router');
const router=express.Router();
// router.route("/").get((req,res)=>res.send("Hello world"));
router.route("/movie/:id").get(ReviewsController.apiGetReviews);
router.route("/new").post(ReviewsController.apiPostReview);
router.route("/:id")
.get(ReviewsController.apiGetReviews)
.put(ReviewsController.apiUpdateReview)
.delete(ReviewsController.apiDeleteReview)
export default router;
moviesdb.js:
import app from './server.js';
import ReviewsDAO from "./dao/reviewsDAO.js";
import mongodb from 'mongodb';
import dotenv from 'dotenv';
const MongoClient=mongodb.MongoClient;
//Load the environment variables from the .env file
dotenv.config();
//Access the environment variables
const mongo_username = process.env.MONGO_USERNAME;
const mongo_password = process.env.MONGO_PASSWORD;
uri=`mongodb+srv://${mongo_username}:${mongo_password}@cluster0.b5f7prn.mongodb.net/test`;
const port=4444;
MongoClient.connect(
uri,
{
maxPoolSize: 50,
wtimeoutMS: 2500,
useNewUrlParser: true
})
.catch(err => {
console.error(err.stack)
console.error("Error connecting to the database:", err.message)
process.exit(1)
})
.then(async client => {
await ReviewsDAO.injectDB(client)
app.listen(port, () => {
console.log(`listening on port ${port}`)
})
})
server.js:
import express from "express"
import cors from "cors"
import reviews from "./api/reviews.route.js"
const app = express()
app.use(cors())
app.use(express.json())
app.use("/api/v1/reviews", reviews)
app.use("*", (req, res) => res.status(404).json({error: "not found"}))
//to listen to the router
app.listen( 4444, () => {
console.log(`Listening on port 4444`);
});
export default app