push array of strings to mongoDB with mongoose

Viewed 141

I am not sure how to go about saving an array of strings from an input field to mongoDB with mongoose.

Ideally I would like to enter text several times in the same input field that creates an array. So I would end up having something like this.

title: "This is my Title"

actions: [ "walking", "smiling", "laughing"]

EJS File:

<form action="/blogs" method="POST">
        <input type="text" placeholder="title" name="title" id="title" > 
        <input type="text" name="actions" id="actions" > 
    <button >submit</button>
</form> 

blog.js

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const blogSchema = new Schema(
  {
    title: {
      type: String,
      required: true,
    },
    actions: [
      {
        type: String,
      },
    ],
  },
  { timestamps: true }
);

const Blog = mongoose.model("Blog", blogSchema);
module.exports = Blog;

app.js

app.post('/blogs', (req, res) =>  {
  
  const blog = new Blog ({
    title: req.body.title,
    actions: req.body.tags,
  });


  blog.save()
  .then((result) => {
    res.redirect('/blogs')
    
  })
  .catch((erro) => {
    console.log(erro)
  })
})

Any guide on how to approach this? Right now my only solution is to create multiple input fields, but that is not correct.

2 Answers

If the actions tags are predefined and specific you can use html select multiple. That way actions property will be sent as an array of strings

<form action="/blogs" method="POST">
        <input type="text" placeholder="title" name="title" id="title" > 
        <label for="actions">Actions:</label>
        <select name="actions" id="actions" multiple>
            <option value="walking">walking</option>
            <option value="smiling">smiling</option>
            <option value="laughing">laughing</option>
        </select>
    <button >submit</button>
</form>

And inside the controller you handle this way

  // req.body.actions is already an array.
  const blog = new Blog(req.body);
  blog.save()
  .then((result) => {
    res.redirect('/blogs')
    
  })
  .catch((erro) => {
    console.log(erro)
  })

If, in any case, you want to use a text input to write the actions separated by space or comma, the actions property will be sent as a string. Then you can convert the string to array inside the controller.

// In case of multiple spaces, replace with single space. 
// Then split string to array of strings
let actions = req.body.actions.replace(/ +/g, " ").split(" ")

const blog = new Blog ({
    title: req.body.title,
    actions
});
// rest of code

Whatever you choose to do, the actions will be stored as array of strings in the database.

Possibly you are sending an array as a string to the mongo. You can check this by checking the type of req.body.tags like so:

console.log(typeof req.body.tags)

If this returns a String, make sure you send the content as JSON to the database.

Related