-1

I want to insert data in mongodb where one field is of array of an objects type.I am unable to get how I can add data into array field along with other fields defined in mongoose schema. When I am trying to post data using POSTMAN with below configurations as shown in screenshot:

Its showing games array is empty and showing below error

 games: CastError: Cast to embedded failed for value "'San and'" (type string) at path "games"

enter image description here

Below is my code:

db.js

const mongoose = require('mongoose');
const dotEnv = require('dotenv').config();

const uri = process.env.URI;

const connect = mongoose.connect(uri,{useNewUrlParser:true,useUnifiedTopology:true})
                .then(() => console.log("Database connected"))
                .catch((err) => {
                   console.log("Something went wrong",err);
                   process.exit(1);
               });

module.exports = connect; 

publisher.js

const mongoose = require('mongoose');

const publisherSchema = new mongoose.Schema({

  company_name:{
    type: String
  },
  website:{
    type: String
  }
  games: [{
    date: Date,
    name: String
   }]

 });

const publisher = mongoose.model('Publisher',publisherSchema);
module.exports = publisher;

Two fields can be inserted as given in below code but How Can I add array field along with these two fields.

server.js

const express = require('express');
const connect = require('./db.js');
const publisher = require('./models/publisher.js');
const gaming = require('./models/game.js');

const app = express();

const port = process.env.PORT || 3000;

app.use(express.json());
app.use(express.urlencoded({ extended: true }))

app.post('/publish',async (req,res) => {

const { company_name,website,games } = req.body;

const insert = new publisher({company_name,website,games});

try{
    const data = await insert.save();
    res.send(data); 
}
catch(err){
    console.log(err);
}

});

app.listen(port, () => console.log(`App is up and runnning at ${port}`));

Someone let me know how can I perform this task.

Digvijay
  • 2,887
  • 3
  • 36
  • 86
  • 2
    same as other 2 fields, just pass third array field along with other fields. – turivishal Oct 04 '21 at 16:57
  • I tried it but it not inserting into array filed. I have attached POSTMAN screenshot in my post take a look. – Digvijay Oct 04 '21 at 17:13
  • 1
    You did not pass that field in actual code `new publisher({company_name,website});`, second the postman request array field's value is string, change key name `games[0]` and for more index add new field in request and increment index. – turivishal Oct 04 '21 at 17:17
  • 1
    You are passing the games array wrong from postman, pass it like [this](https://stackoverflow.com/a/53876323/7177029). Also as @turivishal said destructure the games property in the controller and put it in the Publisher constructor. – Kunal Mukherjee Oct 04 '21 at 17:18
  • Its showing this error after destructering games value and added it as a filed ` games: CastError: Cast to embedded failed for value "'San and'" (type string) at path "games"` – Digvijay Oct 04 '21 at 17:23
  • In my postman I have changed `games` key to `games[ ]` – Digvijay Oct 04 '21 at 17:24
  • Did this work for you? – Angus Ryer Oct 04 '21 at 18:00
  • @Angus your answer is not working.. – Digvijay Oct 06 '21 at 12:57
  • Sorry haven't had a chance to revise. Did you solve the issue? – Angus Ryer Oct 06 '21 at 17:33
  • No its not resolved yet I have added screenshots of an error in my post.Plz let me know what I am doing wrong. – Digvijay Oct 07 '21 at 12:28

1 Answers1

0

You're getting the CastError because mongodb is only receiving the string "San and" for the games array schema field type.

In Postman, you need to change the games key to games[0][name] to be able to pass "San and" as the game's name. @turivishal and @KunalMukherjee both mention this in the original comments. To add additional array items, you can do so like this in Postman, using x-www-form-urlencoded:

key: games[0][name] value: San and
key: games[0][date] value: 2020-01-01
key: games[1][name] value: The Great Game
key: games[1][date] value: 2020-01-02
etc...

Alternatively, you can write the JSON directly by selecting the raw post body entry method instead of x-www-form-urlencoded. Like this:

{
    "company_name": "roveo",
    "website": "www.ro.com",
    "games": [
        {
            "date": "2020-01-01",
            "name": "San and"
        },
        {
            "date": "2020-01-02",
            "name": "The Great Game"
        }
    ]
}

Here is the output I get in PostMan using this method:

enter image description here

And the DB documents in MongoDB:

enter image description here

Here is the github repo with working code: https://github.com/angusryer/mongo-play

You'll have to point the mongodb uri to your own Cloud Atlas or local server instance. Set up Cloud Atlas by these steps here.


Before the question was updated, it looks like like you'd forgotten to extract the games array from your req.body in server.js as well:

const { company_name, website, games } = req.body; // <-- missed `games`

const insert = new publisher({company_name, website, games}); // <-- and `games` here too

try{
    const data = await insert.save();
    res.send(data); 
}
catch(err){
    console.log(err);
}

Angus Ryer
  • 114
  • 2
  • 10
  • on doing your solution its showing this error ` games: CastError: Cast to embedded failed for value "'San and'" (type string) at path "games"` – Digvijay Oct 04 '21 at 17:24
  • Very late, but for posterity, I've updated the answer. – Angus Ryer Dec 16 '21 at 04:03
  • its not working array is still empty – Digvijay Dec 17 '21 at 12:18
  • That's odd. On the very first time I sent this POST request, mongo db did not receive the array for some reason. This could have been a caching error on my end--not sure. Either way, every subsequent POST _did_ behave normally, so I've updated my answer to show the result I'm getting. I believe this answers the original question. If it's still not working on your end and you have all of the code above, then there may be another problem. – Angus Ryer Dec 17 '21 at 16:42