简体   繁体   中英

How do I update a Mongoose Model Array?

I am fairly new to programming so I apologize if there is a very simple answer to this question.

I am trying to create a simple website where users can upload multiple images and have those images be displayed somewhere else on the website. I am accomplishing this with Mongoose, Express, and Node. I am using Multer as the uploading middleware and I am also using body parser which I've heard can cause complications when used with Multer. I am using the Cloudinary API to upload and host the uploaded images.

Ideally, the user would select which images they want to upload, those images would be uploaded to Cloudinary, then the direct link to each image would be saved in the Mongoose Model for that particular post and then each image would be displayed using the image link that has been saved.

So far, I have everything working perfectly except for one issue. The issue that I am running into is when I try to push the supplied link for the uploaded image into the Mongoose Model array, I receive an error and I cannot figure out a workaround.

Here is the code where the images are uploaded and pushed into the array:

var imageLength;
var newImage = new Array();
router.post("/", isLoggedIn, upload.array("image"),function(req, res){
    image: [];
    imageLength = req.files.length;
    for(var i = 0; i < imageLength; i++){
        cloudinary.uploader.upload(req.files[i].path, function(result) {
            // add cloudinary url for the image to the campground object under image property
            newImage.push(result.secure_url);
            console.log(newImage[i-1]);
            console.log(req.body);
            req.body.campground.image.push(newImage[i-1]);
            console.log(req.body);
        });
    }

Here is the Mongoose Model for "campground":

var mongoose = require("mongoose");

var campgroundSchema = new mongoose.Schema({
   name: String,
   image: [String],
   image_id: [String],
   description: String,
   author: {
     id: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "User"
     },
     username: String
   },
   comments: [
      {
         type: mongoose.Schema.Types.ObjectId,
         ref: "Comment"
      }
   ]
});

module.exports = mongoose.model("Campground", campgroundSchema);

And here is the error that I receive:

https://res.cloudinary.com/jpisani/image/upload/v1525280683/r1cs0zmjrznopot7lmu9.jpg
{ campground: 
   { name: 'g',
     description: 'g',
     author: { id: 5aaaf25986f338289129f8ea, username: 'frff' } } }
/home/ubuntu/workspace/YelpCamp/v10/routes/campgrounds.js:50
            req.body.campground.image.push(newImage[i-1]);
                                     ^

TypeError: Cannot read property 'push' of undefined

As you can see, the image successfully uploaded to Cloudinary and I have a direct link to that image. The issue lies in console.log(req.body); . There is no image property listed which prevents me from pushing the link into the image array.

I understand that req.body only contains what has been submitted by the user but I have not found a solution to this problem with any other method.

Here is the code for the create a new post page:

<div class="row">
    <h1 style="text-align: center">Create a New Campground</h1>
    <div style="width: 30%; margin: 25px auto;">
        <form action="/campgrounds" method="POST" enctype="multipart/form-data">
            <div class="form-group">
                <input class="form-control" type="text" name="campground[name]" placeholder="name">
            </div>
            <div class="form-group">
                <label for="image">Image</label>
                <input type="file" id="image" name="image" accept="image/*" multiple required>
            </div>
            <div class="form-group">
                <input class="form-control" type="text" name="campground[description]" placeholder="description">
            </div>
            <div class="form-group">
                <button class="btn btn-lg btn-primary btn-block">Submit!</button>
            </div>
        </form>
        <a href="/campgrounds">Go Back</a>
    </div>
</div>

As you can see, the image upload portion of this code(found in the center) is named "image" which should make the image array in the Mongoose Model appear when I console.log(req.body); but it does not seem to do this.

If any information is required please ask, I will respond promptly. Any help would be greatly appreciated. Thanks in advance.

Edit : A solution has been found! For anyone coming across this in the future, here is the answer to the problem.

//create - add new campground to DB
router.post("/", isLoggedIn, upload.array("campground[image]"), async function(req, res){
    // add author to campground
    req.body.campground.author = {
        id: req.user._id,
        username: req.user.username
    };

    req.body.campground.image = [];
    for (const file of req.files) {
        let result = await cloudinary.uploader.upload(file.path);
        req.body.campground.image.push(result.secure_url);
    }

    Campground.create(req.body.campground, function(err, campground) {
        if (err) {
            return res.redirect('back');
        }
        res.redirect('/campgrounds/' + campground.id);
    });
});

The error is because in your req.body.campground.image there is no image property available, that is undefined and you are trying to push onto an undefined instead of an array in the following line

req.body.campground.image.push(newImage[i-1]);

try the following:

req.body.campground.image = req.body.campground.image || [];
req.body.campground.image.push(newImage[i-1]);

If the property exists, well and good otherwise assign it an empty array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM