Create/Launch new Product API +Update an Delete Product by Admin, Get Product Details by customer API Nodejs , MongoDB MERN Stack
// Create Required following files mentioned in previous post = https://vasubirla.blogspot.com/2023/02/register-new-user-login-user-delete.html
config.env
Server.js
//app.js
/utilsfolder/errorhander.js
/utils/jwtToken.js file
3. /utils/sendEmail.js file
//Create Product Model - and import it in ProductController
//ProductModel.js
const mongoose = require('mongoose'); 
const ProductSchema = new mongoose.Schema({
    name: {
        type:String,
        required:[true,"please enter produt name"],
        trim:true
    },
    description: {
        type:String,
        required:[true,"please add product description"]
    },
    price: {
        type:Number,
        required:[true,"Product Price is required"],
        maxLength:[8,"price cannot be exceed 8 character"]
    },
    ratings: {
        type:Number,
        default:0
    },
    image: [
        {
            public_id: {
                type:String,
                required:true
            },
            url: {
                type:String,
                required:true
            }
        }         
    ],
    category: {
        type:String,
        required:[true,"Please enter Product Category"]
    },
    stock:{
        type:Number,
        required:[true,"Product stoke limit required"],
        maxLength:[4,"stoke cannot be exceed 4 char"],
        default:1
    },
    numOfReviews:{
        type:Number,
        default:0
    },
    reviews: [
        {
            user:{
                type: mongoose.Schema.ObjectId,
                ref:"user",
                required:true
            },
            name:{
                type:String,
                required:true
            },
            rating:{
                type:Number,
                required:true
            },
            comment:{
                type:String,
                required:true
            }
        }
    ],
    createdAt:{
        type:Date,
        defualt:Date.now
    }
 })
 module.exports = mongoose.model("Product",ProductSchema)
//Create ProductController.js and import it in route
//ProductController.js 
const Product = require('../models/productModel');
const ErrorHander = require('../utils/errorhander');
const catchAsyncError = require('../middleware/catchAsyncError')
const ApiFeatures = require('../utils/apifeatures')
//create/add or Launch New Products to sell on website  --by Admin
exports.createProduct = catchAsyncError(
    async (req,res,next)=>{
        const product = await Product.create(req.body);
        res.status(201).json({
            success:true,
            product 
        })
    }
)
//==create Product API Testing on Postman 
//Get Products Details on HomePage by different Customers or Visiters
exports.getAllProduct =catchAsyncError( async (req,res)=>{
        console.log("Hited from React End")
    const resultPerPage = 5; // show 5 product per page 
    const productCount = await Product.countDocuments()
    const apiFeatures = new ApiFeatures(Product.find(),req.query).search().filter().pagination(resultPerPage)
    const products = await apiFeatures.query //await Product.find()
    res.status(200).json({
        success:true,
        products,
        productCount
    });
}
)
//== Get products API Testing on Postman = 
//get perticular Product Details 
    exports.getProductDetails =catchAsyncError( async (req,res,next)=>{
        const product = await Product.findById(req.params.id)
        if(!product){
            return next(new ErrorHander("Product Not Found",404))
        }
        else{
            res.status(200).json({
                success:true,
                product
            })
        }
    }
    )
//=====Open Perticular Product DEtails API Testing - Postman (with wrong ID)//Update Product -- Admin
exports.updateProduct = catchAsyncError( async (req,res,next)=>{
    let product = await Product.findById(req.params.id)
    if(!product){
        res.status(500).json({
            success:false,
            message:"Product not found"
        })
    }
    product = await Product.findByIdAndUpdate(req.params.id,req.body,{
        new:true,
        runValidators:true,
        useFindAndModify:false
    })
    res.status(200).json({
        success:true,
        product
    })
}
)
//========Update Product API testing - only Admin can update - Postman 
//=======delete Products============================= 
exports.deleteProduct =catchAsyncError(  async(req,res,next)=>{
    const product = await Product.findById(req.params.id)
    if(!product){
        res.status(500).json({
            success:false,
            message:"Product not found"
        }) // or we can use this line  return next(new ErrorHander("Product Not Found",404))
    }
    else {
        await Product.findByIdAndDelete(req.params.id,req.body); 
        res.status(200).json({
            success:true,
            message:"Product Deleted Successfully"
        })
    }
}
)
//Give Product Review or Update it if already exists =========================================
exports.createProductReview = catchAsyncError(async(req,res,next)=>{
        const { rating,comment, productId} = req.body;
    const review = {
        user:req.user.id,
        name:req.user.name,
        rating,
        comment
    }
    const product = await Product.findById(productId); 
        const isReviewed = product.reviews.find(
           (rev)=>rev.user.toString()=== req.user._id.toString()
            ) 
        //here rev.user who already made reviewed and req.user._id is also your Id - If Both ID is same and Review already exists by you then it will be updated
        if(isReviewed)
        {
           product.reviews.forEach(rev=>{
            if(rev.user.toString()=== req.user._id.toString())
            {                
             rev.rating = rating,
             rev.comment = comment
            }
           }) 
        }
        else 
        {
            product.reviews.push(review)
            product.numOfReviews = product.reviews.length
        }
        //Overall Rating = Total Rating divided by length of Rating
        let avg = 0
        product.reviews.forEach( rev=>{
            avg=avg+rev.rating
        }) 
        product.ratings = avg/product.reviews.length
        await product.save({validateBeforeSave:false})
        res.status(200).json({
            success:true,
            message:"You have rated this Product Successfully !!"
        })
})
//Get All Reviews of Product ======== 
exports.getProductReviews = catchAsyncError(async (req,res,next)=>{
    const product = await Product.findById(req.query.id)
    if(!product){
        return next(new ErrorHander("Product or Review Found ",404))
    }
    else{
        res.status(200).json({
            success:true,
            reviews:product.reviews
        })
    }
})
//Delete Review of Product 
exports.deleteReview = catchAsyncError(async (req,res,next)=>{
    const product = await Product.findById(req.query.productId)
    if(!product){
        console.log("No Product found")
        return next(new ErrorHander("Product Not Found",404))
    }
    else{
        //now in review that all reviews are assigned which we dont want to delete  using filter 
        const reviews = product.reviews.filter(rev=> rev._id.toString() !== req.query.id.toString()); 
        // now after deleteing review Overall Averaging Rating, Num of rating also should be updated 
        let avg = 0
            reviews.forEach( rev=>{
            avg=avg+rev.rating
        }) 
        const ratings = avg/reviews.length         
        const numOfReviews = reviews.length 
        await Product.findByIdAndUpdate(req.query.productId,{
            reviews ,ratings, numOfReviews
        },
        {
            new:true,
            runValidators:true,
            useFindAndModify:false
        })
        res.status(200).json({
            success:true,
            message:"Your Review has Been deleted "
        })
    }
})  
//Create ProductRoute.js
//===== ProductRoute.js
const express = require('express');
const {getAllProduct, 
    createProduct,
     updateProduct,
      deleteProduct,
       getProductDetails, createProductReview, getProductReviews, deleteReview} = require('../controllers/productController.js');
const { isAuthenticatedUser, authorizeRoles } = require('../middleware/auth.js');
const router = express.Router();
router.route('/products').get(getAllProduct);
router.route('/products/new').post(isAuthenticatedUser, authorizeRoles("admin"),createProduct);
router.route('/products/:id').put(isAuthenticatedUser, authorizeRoles("admin"),updateProduct);
router.route('/products/:id').delete(isAuthenticatedUser, authorizeRoles("admin"),deleteProduct);
router.route('/products/:id').get(getProductDetails );
router.route('/review').put(isAuthenticatedUser, createProductReview )
router.route('/reviews').get(getProductReviews)
router.route('/reviews').delete(isAuthenticatedUser,deleteReview)
module.exports = router
=================== End===============
Comments
Post a Comment