indee423
indee423

Reputation: 491

Mongoose: push a string into array

I have a website where any logged-in user can leave a review for the shop.

So basically I have two schemas:

const journalSchema = new mongoose.Schema({
  title: String,
  category: String,
  subcategory: String,
  rating: Number,
  review: [{type: String}],
  link: String,
  description: String,
});


const userSchema = new mongoose.Schema ({
  username: String,
  password: String,
  journal: [{type: mongoose.Schema.Types.ObjectId, ref: 'Journal'}]
});



const Journal = mongoose.model("Journal", journalSchema);
const User = mongoose.model("User", userSchema);

form from the ejs file:

  <div class="container my-3">
    <h1>Compose</h1>
    <form class="" action="/stats" method="post">
      <div class="form-group">

        <label for="review">Description</label>
        <textarea id="review" class="form-control" name="journalReview" rows="5" cols="30"></textarea>
      </div>
      <button class="btn btn-primary my-2" type="submit" name="button">Publish</button>
    </form>
  </div>

post route:

app.post("/stats", function(req, res){

  if(req.isAuthenticated()){
    const favJournal = req.body.savedJournal;
    const userId = req.user.id;
    const userReview = req.body.journalReview;

    User.findById(userId, function(err, foundUser){
    Journal.findById(favJournal, function(err, foundJournal){

      if(err){
        console.log(err);
      }


      else{
        if(foundUser){
          foundJournal.review.push(userReview);
          foundJournal.save(function(){
            console.log(foundJournal);
          });
          foundUser.journal.addToSet(foundJournal);
          foundUser.save(function(){
            res.redirect("/favourite");
          });
        }


        }


    });

    })
    .populate('journal')
    .exec(function(err, user){
      if(err) return handleError(err);
    });
  }

  else{
    res.redirect("/login");
  }

});

Every time I try to push review from the ejs file I keep getting this error:

events.js:353
      throw er; // Unhandled 'error' event
      ^

TypeError: Cannot read property 'review' of null
    at C:\Users\HelloThere\Desktop\miesto\app.js:337:24
    at C:\Users\HelloThere\Desktop\miesto\node_modules\mongoose\lib\model.js:5065:18
    at processTicksAndRejections (internal/process/task_queues.js:77:11)
Emitted 'error' event on Function instance at:
    at C:\Users\HelloThere\Desktop\miesto\node_modules\mongoose\lib\model.js:5067:15
    at processTicksAndRejections (internal/process/task_queues.js:77:11)

I tried different solutions from similar posts. Like mongoose methods: findOneAndUpdate and updateOne, but they just return null.

Upvotes: 0

Views: 2496

Answers (2)

indee423
indee423

Reputation: 491

I think I figured out the cause of the problem, I have two post forms in my ejs file, and since both forms have submit button with nothing differentiating them, only the first form gets called in the post route.

Upvotes: 0

Ikdemm
Ikdemm

Reputation: 2373

Instead of getting the shop and manipulating it with JavaScript code and then saving it back to the database, you could achieve this through findOneAnUpdate and $push operator. For instance, this query

Shop.findById( shopId, (shop) => {
  shop.products.push(product);
  shop.save();
}

can be done through this query

Shop.findOneAndUpdate(
   { _id: shopId }, 
   { $push: { 
             products: product
           } 
   })

$pop, $push, and $pull are very powerful tools to manipulate arrays in Mongoose. Take a look at the docs.

For the error you're getting, I think you're getting because you're passing a wrong journalId to findById. Check with MongoDB Compass if you do have a document with that id favJournal

Upvotes: 1

Related Questions