My form data array isn't POSTing to my mongodb the way I want it to

398 views
Skip to first unread message

blue wolf

unread,
Jun 25, 2016, 1:14:39 PM6/25/16
to mongodb-user
My array in my MongoDB is not being structured the way I want it to be. I am using node.js, Express, and Mongoose.
.
Here is my schema:

   
var fruitSchema = new schema ({
        fruitName
: {type: String},
        priceArray
: {type: Array}
   
});



Here is part of the code that pushes new priceArray items:

   
Fruit.findOneAndUpdate({fruitName: req.body.fruitName},
               
{
                $push
: {
                    priceArray
: {
                        price
: req.body.price,
                        description
: req.body.description
                   
}
               
}
           
}



And here is the form:

   
 <form method="POST" action="/fruit">
   
<div class='form-group'>
       
<label for="fruitName">Fruit Name</label>
       
<input type="text" name="fruitName" id="fruitName"/>
   
</div>
   
<div>
       
<label for="price0">Price</label>
       
<input type="text" name="price[0]" id="price0"/>
       
       
<label for="description0">Description</label>
       
<input type="text" name="description[0]" id="description0"/>
   
</div>
   
<div>
       
<label for="price1">Price</label>
       
<input type="text" name="price[1]" id="price1"/>
       
       
<label for="description1">Description</label>
       
<input type="text" name="description[1]" id="description1"/>
   
</div>
   
<input type="submit" value="submit">
   
</form>



So what's all this saying? Basically, a user can enter a name of a fruit, and then they would enter the **price** of the fruit, and give a **description**. So the **'price'** and **'description'** pieces are always together. The form allows for multiple inputs of price/description pairs (the example form I've posted here allows for 2 pairs, but the real form allows for unlimited pairs).

In my MongoDB, this is how the above code inserts the form data:

   
 {
   
"fruitName" : "test fruit",
   
"priceArray" : [
       
{
           
"price" : [
               
"$2.00",
               
"$3.00"
           
],
           
"description" : [
               
"Good",
               
"Bad"
           
]
       
}



Here is how I **want** it to look like:

   
 {
   
"fruitName" : "test fruit",
   
"priceArray" : [
       
{
           
"price" : "$2.00"
           
"description: "Good"
        }
        {
            "
price" : "$3.00"
            "
description" : "Bad"
        }
        ]
    }



How can I fix this?

Kevin Adistambha

unread,
Jul 8, 2016, 3:12:06 AM7/8/16
to mongodb-user

Hi,

My array in my MongoDB is not being structured the way I want it to be. I am using node.js, Express, and Mongoose

There are two issues with your code. First is the form:

<input type="text" name="price[0]" id="price0"/>
<input type="text" name="description[0]" id="description0"/>
<input type="text" name="price[1]" id="price1"/>
<input type="text" name="description[1]" id="description1"/>

this form will create an array like you’ve seen, e.g. {price:[price0, price1], description:[description0, description1]}. If you want to create paired {priceArray: [{price:..., description:...},...]} array of objects instead, the form would have to be modified to reflect the structure you want. For example:

<input type="text" name="priceArray[0][price]" id="price0"/>
<input type="text" name="priceArray[0][description]" id="description0"/>
<input type="text" name="priceArray[1][price]" id="price1"/>
<input type="text" name="priceArray[1][description]" id="description1"/>

note the content of the name attributes to reflect the output structure you want.

The second issue is the Mongoose code that pushes new priceArray items:

Fruit.findOneAndUpdate({fruitName: req.body.fruitName},
                {
                $push: {
                    priceArray: {
                        price: req.body.price,
                        description: req.body.description
                    }
                }
            }

in this form, it will push the new array into an array. When you attempt to add to an existing fruitName, the resulting document will look like:

{
  "fruitName": "q",
  "priceArray": [
    [ {"description": "1", "price": "1"}, {"description": "1", "price": "1"} ],
    [ {"description": "2", "price": "2"}, {"description": "2", "price": "2"} ]
  ],
}

which is probably not what you have in mind (array within another array). If you’re using MongoDB 2.4 and above, you can use the $each operator, e.g.:

Fruit.findOneAndUpdate(
    {fruitName: req.body.fruitName},
    {$push: {priceArray: {$each: req.body.priceArray}}},
    {upsert:true, new:true},
    function(err,fruit) {
        if (err) return console.error(err)
        console.log(fruit)
    }
)

which will result in:

{
  "fruitName": "q",
  "priceArray": [
    {"description": "1", "price": "1"},
    {"description": "1", "price": "1"},
    {"description": "2", "price": "2"},
    {"description": "2", "price": "2"}
  ],
}

The above snippets were tested with MongoDB 3.2.7, Mongoose 4.5.3, and Express 4.14.

Best regards,
Kevin

Reply all
Reply to author
Forward
0 new messages