Getting a ValidationError in mongoose when trying to write new or updates to my mongoDB on mlab

1.2k views Asked by At

I am getting a validationError on my little travel related website I setup over a year ago. I had no problems when creating the initial posts, but now after a long break from adding anything to the site, I am getting errors whenever I try to add or edit a post. The only thing I can think of is maybe something has been updated in mongoose or MongoDB or something else. I only know what I know about webDev from what I learned watching a full stack webDev course on Udemy, and as informative as it was, I only know how to do something the way they showed in the course. I have searched alot and have found a number of questions with validationErrors, but none of the solutions seem to address the problem I have since all of this was working code, and there have been no changes to my code since the last time I used the website.

Here is my error log from Heroku:

Error [ValidationError]: Travel validation failed: tags: Cast to String failed for value "[ 'e' ]" at path "tags"
2020-01-29T04:49:40.091426+00:00 app[web.1]:     at ValidationError.inspect (/app/node_modules/mongoose/lib/error/validation.js:61:24)
2020-01-29T04:49:40.091429+00:00 app[web.1]:     at formatValue (internal/util/inspect.js:563:31)
2020-01-29T04:49:40.091432+00:00 app[web.1]:     at inspect (internal/util/inspect.js:221:10)
2020-01-29T04:49:40.091434+00:00 app[web.1]:     at formatWithOptions (internal/util/inspect.js:1693:40)
2020-01-29T04:49:40.091437+00:00 app[web.1]:     at Object.Console.<computed> (internal/console/constructor.js:272:10)
2020-01-29T04:49:40.091439+00:00 app[web.1]:     at Object.log (internal/console/constructor.js:282:61)
2020-01-29T04:49:40.091442+00:00 app[web.1]:     at /app/routes/travels.js:137:21
2020-01-29T04:49:40.091444+00:00 app[web.1]:     at /app/node_modules/mongoose/lib/utils.js:268:11
2020-01-29T04:49:40.091446+00:00 app[web.1]:     at /app/node_modules/mongoose/lib/model.js:4810:21
2020-01-29T04:49:40.091448+00:00 app[web.1]:     at _done (/app/node_modules/mongoose/lib/model.js:3101:16)
2020-01-29T04:49:40.091450+00:00 app[web.1]:     at /app/node_modules/mongoose/lib/model.js:3116:18
2020-01-29T04:49:40.091453+00:00 app[web.1]:     at callbackWrapper (/app/node_modules/mongoose/lib/model.js:3070:20)
2020-01-29T04:49:40.091455+00:00 app[web.1]:     at /app/node_modules/mongoose/lib/model.js:4791:16
2020-01-29T04:49:40.091456+00:00 app[web.1]:     at /app/node_modules/mongoose/lib/utils.js:268:11
2020-01-29T04:49:40.091458+00:00 app[web.1]:     at /app/node_modules/mongoose/lib/model.js:4810:21
2020-01-29T04:49:40.091459+00:00 app[web.1]:     at /app/node_modules/mongoose/lib/model.js:485:16 {
2020-01-29T04:49:40.091461+00:00 app[web.1]:   errors: {
2020-01-29T04:49:40.091463+00:00 app[web.1]:     tags: MongooseError [CastError]: Cast to String failed for value "[ 'e' ]" at path "tags"
2020-01-29T04:49:40.091464+00:00 app[web.1]:         at new CastError (/app/node_modules/mongoose/lib/error/cast.js:39:11)
2020-01-29T04:49:40.091466+00:00 app[web.1]:         at model.$set (/app/node_modules/mongoose/lib/document.js:1201:9)
2020-01-29T04:49:40.091467+00:00 app[web.1]:         at model._handleIndex (/app/node_modules/mongoose/lib/document.js:935:14)
2020-01-29T04:49:40.091469+00:00 app[web.1]:         at model.$set (/app/node_modules/mongoose/lib/document.js:879:22)
2020-01-29T04:49:40.091471+00:00 app[web.1]:         at model.Document (/app/node_modules/mongoose/lib/document.js:137:12)
2020-01-29T04:49:40.091473+00:00 app[web.1]:         at model.Model (/app/node_modules/mongoose/lib/model.js:102:12)
2020-01-29T04:49:40.091474+00:00 app[web.1]:         at new model (/app/node_modules/mongoose/lib/model.js:4611:15)
2020-01-29T04:49:40.091476+00:00 app[web.1]:         at /app/node_modules/mongoose/lib/model.js:3077:22
2020-01-29T04:49:40.091477+00:00 app[web.1]:         at /app/node_modules/mongoose/lib/model.js:3113:7
2020-01-29T04:49:40.091479+00:00 app[web.1]:         at Array.forEach (<anonymous>)
2020-01-29T04:49:40.091480+00:00 app[web.1]:         at /app/node_modules/mongoose/lib/model.js:3112:15
2020-01-29T04:49:40.091482+00:00 app[web.1]:         at Object.promiseOrCallback (/app/node_modules/mongoose/lib/utils.js:261:12)
2020-01-29T04:49:40.091483+00:00 app[web.1]:         at Function.create (/app/node_modules/mongoose/lib/model.js:3047:16)
2020-01-29T04:49:40.091485+00:00 app[web.1]:         at /app/routes/travels.js:135:12
2020-01-29T04:49:40.091493+00:00 app[web.1]:         at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)
2020-01-29T04:49:40.091494+00:00 app[web.1]:         at next (/app/node_modules/express/lib/router/route.js:137:13) {
2020-01-29T04:49:40.091496+00:00 app[web.1]:       stringValue: `"[ 'e' ]"`,
2020-01-29T04:49:40.091497+00:00 app[web.1]:       kind: 'String',
2020-01-29T04:49:40.091499+00:00 app[web.1]:       value: [Array],
2020-01-29T04:49:40.091500+00:00 app[web.1]:       path: 'tags',
2020-01-29T04:49:40.091502+00:00 app[web.1]:       reason: [MongooseError],
2020-01-29T04:49:40.091503+00:00 app[web.1]:       message: `Cast to String failed for value "[ 'e' ]" at path "tags"`,
2020-01-29T04:49:40.091505+00:00 app[web.1]:       name: 'CastError'
2020-01-29T04:49:40.091506+00:00 app[web.1]:     }
2020-01-29T04:49:40.091507+00:00 app[web.1]:   },
2020-01-29T04:49:40.091509+00:00 app[web.1]:   _message: 'Travel validation failed',
2020-01-29T04:49:40.091511+00:00 app[web.1]:   name: 'ValidationError'
2020-01-29T04:49:40.091512+00:00 app[web.1]: }

Here is my schema for making a "travel" entry:

var mongoose = require("mongoose");

var reviewPhoto = new mongoose.Schema({
    imgUrl: String,
    info:   String
});

var travelSchema = new mongoose.Schema({
    
    name:           String,
    category:       String,
    tags:           String,
    splashText:     String,
    body:           String,
    adRight:        String,
    photos: [ reviewPhoto ]
    
    }, { timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' } }
);

module.exports = mongoose.model("Travel", travelSchema);

Here is my ejs that has my travel form that I enter my data into when creating a new travel post. There is a way to add more reviewPhoto's on the site that adds extra entries to the array of photos but that code is not included since it should not be any part of the problem:

<form action="/travel_new" method="POST">
                    <div id="reviewLeft">
                        <input type="text" name="travel[name]" placeholder="Travel Title" required>
                        <input type="text" name="travel[splashText]" placeholder="Splash Text" required>
                        <input type="text" name="travel[category]" placeholder="Category: ex: Park - Campground - Monument" required>
                        <input type="text" name="travel[tags]" id="tagField" placeholder="Tags - separate tags by a comma ex: sunset,national park,sky" required>
                        <input type="text" name="travel[adRight]" placeholder="need Ad Target url and the image Banner Url separated by comma ,  use none for no ad" required>
                        <textarea id="txDescription" name="travel[body]" placeholder='Start Article' required></textarea>
                        
                    </div>
                    
                    <div id="reviewRight" class="style-10">
                        <div class="border">
                            <input type="text" name="reviewPhoto[0][imgUrl]" placeholder="photo url" required>
                            <input type="text" name="reviewPhoto[0][info]" placeholder="photo Info" required>
                        </div>
                        
                    </div>
                    <input id="submitBtn" type="submit">
                </form>

And here is my code on my node.js server for the post route to create a new travel entry:

router.post("/travel_new", isLoggedIn, function(req, res){

    var name     = req.body.travel.name;
    var category = req.body.travel.category || "default";
    var tags     = req.body.travel.tags;
    var splash   = req.body.travel.splashText;
    var body     = req.body.travel.body;
    var adRight  = req.body.travel.adRight  || "none";
    var photos   = req.body.reviewPhoto;
    
    tags = tags.split(",");
    
    //Assemble a variable to send all the review data into the create function for the SCHEMA pattern
    var newTravel = { name: name, category: category, tags: tags, splashText: splash, body: body, adRight: adRight, photos: photos };
    
    Travel.create( newTravel, function(err, travel){ 
        if(err){
            console.log(err);
            res.redirect("travel/new");
        }else{
            // console.log(travel);
            res.redirect("travel");
        }
    });
});

And here is my package.json file if it helps.

{
  "name": "travelSite",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "dependencies": {
    "body-parser": "^1.18.3",
    "ejs": "^2.6.1",
    "express": "^4.16.4",
    "express-session": "^1.15.6",
    "helmet": "^3.15.0",
    "method-override": "^3.0.0",
    "mongoose": "^5.3.12",
    "passport": "^0.4.0",
    "passport-local": "^1.0.0",
    "passport-local-mongoose": "^5.0.1"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node app.js"
  },
  "author": "",
  "license": "ISC"
}

What is very confusing to me, is there is another area on the website where I can add a new photo and each photo has a title , description, and tags that I enter, and it is all using almost identical code to save and update to the mongoDB and the photo section of the website still works fine. It is only the area to add travels. All of this was written at the same time and all worked, and now 9 months later or so, only certain parts of the website do not work. All of the data that is already in the MongoDB is loaded onto the website fine, all the travels that have been entered all load and dispaly fine, so I know there is not a problem with connecting to the MongoDB, nor is it corrupt. The error message seems to show something like it is trying to cast an array to a string, the tags variable should be an array of strings if I recall. This is the problem when writing web code is not your actual job and a hobby that comes and goes every 6 months. I forgot most of what I learned and have to re learn a lot everytime I get the time to write some more web code.!

Thanks for any help that can be given.

E

1

There are 1 answers

1
Sarfraaz On BEST ANSWER

You are passing array to tags in your query, which is defined of String type

So, you must have your schema that supports array of strings & not just string

Make this change in your schema

var travelSchema = new mongoose.Schema({
name:           String,
category:       String,
tags:           [String],
splashText:     String,
body:           String,
adRight:        String,
photos: [ reviewPhoto ]
}, { timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' } }
);