Home > Software design >  Node/JS mongoose REST API How to push a new object into a nested array of objects all in one collect
Node/JS mongoose REST API How to push a new object into a nested array of objects all in one collect

Time:05-14

Noob MERN Stack Dev here, I am building a little food delivery practice web app. I have begun creating a basic RESTful API to serve my food delivery site.

I am currently trying to build out the Database. I have a restaurants collection which contains restaurants each with an image source, title, description and menu. The menu is a nested array. I want to make it so that the user is able to push new menu items into the menu array for their restaurant as well as remove selected items from that array. I have been trying to figure out how to do this with patch but jsut cant seem to find a solution that works. Any help would be much appreciated.

SERVER.JS:

 require("dotenv").config()

const express = require("express");
const mongoose = require("mongoose");
const app = express();



mongoose.connect(process.env.DATABASE_URL)

const db = mongoose.connection

db.on("error", () => console.error(error))
db.once("open", () => console.log("connected to database"))

app.use(express.json())

const subscribersRouter = require("./routes/subscribers")
const restaurantsRouter = require("./routes/restaurants")

app.use("/subscribers", subscribersRouter)
app.use("/restaurants", restaurantsRouter)

app.listen(3000, () => {
    console.log("Server has started on port 3000")
});

SCHEMA & MODEL:

   const mongoose = require("mongoose")


const menueSchema = new mongoose.Schema({
    name: String,
    price: String,
    description: String

})


const restaurantSchema = new mongoose.Schema({
    src: {
        type: String,
        required: true

    },
    title: {
        type: String,
        required: true
    },
    description: {
        type: String,
        required: true

    },
    menue: {
        type: menueSchema,
        required: true
    }

})

module.exports = mongoose.model("restaurant", restaurantSchema)

ROUTE:

const express = require("express")
const router = express.Router()
const Restaurant = require("../models/restaurant")


// Getting All

router.get("/", async (req, res) => {
    try {
        const restaurants = await Restaurant.find()
        res.json(restaurants)
    } catch (err) {
        res.status(500).json({
            message: err.message
        })
    }
})

// Getting One
router.get("/:id", getRestaurant, (req, res) => {
    res.json(res.restaurant)
})

// Creating One
router.post("/", async (req, res) => {
    const restaurant = new Restaurant({
        src: req.body.src,
        title: req.body.title,
        description: req.body.description,
        menue: req.body.menue
    })
    try {
        const newRestaurant = await restaurant.save()
        res.status(201).json(newRestaurant)
    } catch (err) {
        res.status(400).json({
            message: err.message
        })
    }
})

// Updateing One 
router.patch("/:id", getRestaurant, async (req, res) => {
    if (req.body.name != null) {
        res.restaurant.name = req.body.name
    }
    if (req.body.title != null) {
        res.restaurant.title = req.body.title
    }
    if (req.body.description != null) {
        res.restaurant.description = req.body.description
    }
    if (req.body.menue != null) {
        res.restaurant.menue = req.body.menue
    }
    try {
        const updatedRestaurant = await res.restaurant.save()
        res.json(updatedRestaurant)
    } catch (err) {
        res.status(400).json({
            message: err.message
        })
    }
})

// Update Menue 

router.patch("/:id", getRestaurant, async (req, res) => {
    try {
        console.log(res.resturants.menue)


    } catch (err) {

    }
})

// Deleting One
router.delete("/:id", getRestaurant, async (req, res) => {
    try {
        await res.restaurant.remove()
        res.json({
            message: "Deleted Restaurant"
        })
    } catch (err) {
        res.status(500).json({
            message: err.message
        })
    }
})


async function getRestaurant(req, res, next) {

    let restaurant
    try {
        restaurant = await Restaurant.findById(req.params.id)
        if (restaurant == null) {
            return res.status(404).json({
                message: "cannot find Restaurant"
            })
        }
    } catch (err) {
        return res.status(500).jsong({
            message: err.message
        })
    }
    res.restaurant = restaurant
    next()
}

module.exports = router

REQUESTS:

# RESTURANTS

# Get All
GET http://localhost:3000/restaurants


###

# Get One
GET http://localhost:3000/restaurants/627e3012afe6e905cd550c9f

###


# Create One
POST http://localhost:3000/restaurants
Content-Type: application/json

{
    "src": "https://ychef.files.bbci.co.uk/976x549/p04tx3m6.jpg",
    "title": "Joes Burgers",
    "description": "Good Fuggen Burgers",
    "menue": {
        "name": "Burger",
        "price": "R50",
        "description": "A good Fuggen burger"
    }
}

### 

#Delete One on ID

DELETE http://localhost:3000/restaurants/627e68802760c784cc5702c1


###

 #Update One 

PATCH http://localhost:3000/restaurants/627e68f62760c784cc5702c5
Content-Type: application/json

{
   
     
       "menue": {
        "name": "Waffel",
        "price": "R20",
        "description": "A good Fuggen Waffel"
    }
    
}

CodePudding user response:

What I understood about your problem is that you are using two separate collections for restaurants and menu respectively. If you want to push data in menu collection you will have to write a separate query and add restaurant's id in menu collection just to let you know which restaurant has this menu.

Other option is that you can add an array of objects in restaurants collection and name it as menu then push the data in it.

const restaurantSchema = new mongoose.Schema({
src: {
    type: String,
    required: true

},
title: {
    type: String,
    required: true
},
description: {
    type: String,
    required: true

},
menue: {
    type: Array,
    required: true
}})

That would be an easier option...

  • Related