Search code examples
javascriptnode.jsmongoosemongoose-schemabad-request

Error:cast to string failed for value.The error is so irritating


Explanation according to the actual code, the code only returning a bad request error 400 and the blog is not created when I clicked the create button on the front-end but when I console.log the error I got this as shown below

0] Blog create error Error: Blog validation failed: mdesc: Cast to string failed for value "{
[0]   log: { timeTakenInMilliseconds: 28 },
[0]   result: 'What is Lorem Ipsum? Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the indust',
[0]   ranges: [ [ 0, 4 ], [ 24, 40, ' ' ], [ 51, 61, ' ' ] ],
[0]   allTagLocations: [ [ 0, 4 ], [ 24, 29 ], [ 29, 32 ], [ 32, 40 ], [ 51, 60 ] ],
[0]   filteredTagLocations: [ [ 0, 4 ], [ 24, 29 ], [ 29, 32 ], [ 32, 40 ], [ 51, 60 ] ]
[0] }" at path "mdesc"
[0]     at ValidationError.inspect (C:\Users\Hp\Desktop\StuPro\backend\node_modules\mongoose\lib\error\validation.js:47:26)
[0]     at formatValue (internal/util/inspect.js:718:31)
[0]     at inspect (internal/util/inspect.js:287:10)
[0]     at formatWithOptions (internal/util/inspect.js:1910:40)
[0]     at Object.Console.<computed> (internal/console/constructor.js:299:10)
[0]     at Object.log (internal/console/constructor.js:309:61)
[0]     at C:\Users\Hp\Desktop\StuPro\backend\controllers\blog.js:71:21
[0]     at C:\Users\Hp\Desktop\StuPro\backend\node_modules\mongoose\lib\model.js:4838:16
[0]     at C:\Users\Hp\Desktop\StuPro\backend\node_modules\mongoose\lib\helpers\promiseOrCallback.js:16:11
[0]     at C:\Users\Hp\Desktop\StuPro\backend\node_modules\mongoose\lib\model.js:4861:21
[0]     at C:\Users\Hp\Desktop\StuPro\backend\node_modules\mongoose\lib\model.js:500:16
[0]     at C:\Users\Hp\Desktop\StuPro\backend\node_modules\kareem\index.js:246:48
[0]     at next (C:\Users\Hp\Desktop\StuPro\backend\node_modules\kareem\index.js:167:27)
[0]     at next (C:\Users\Hp\Desktop\StuPro\backend\node_modules\kareem\index.js:169:9)
[0]     at Kareem.execPost (C:\Users\Hp\Desktop\StuPro\backend\node_modules\kareem\index.js:217:3)
[0]     at _handleWrapError (C:\Users\Hp\Desktop\StuPro\backend\node_modules\kareem\index.js:245:21) {
[0]   errors: {
[0]     mdesc: CastError: Cast to string failed for value "{
[0]       log: { timeTakenInMilliseconds: 28 },
[0]       result: 'What is Lorem Ipsum? Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the indust',
[0]       ranges: [ [ 0, 4 ], [ 24, 40, ' ' ], [ 51, 61, ' ' ] ],
[0]       allTagLocations: [ [ 0, 4 ], [ 24, 29 ], [ 29, 32 ], [ 32, 40 ], [ 51, 60 ] ],
[0]       filteredTagLocations: [ [ 0, 4 ], [ 24, 29 ], [ 29, 32 ], [ 32, 40 ], [ 51, 60 ] ]
[0]     }" at path "mdesc"
[0]         at SchemaString.cast (C:\Users\Hp\Desktop\StuPro\backend\node_modules\mongoose\lib\schema\string.js:610:11)
[0]         at SchemaString.SchemaType.applySetters (C:\Users\Hp\Desktop\StuPro\backend\node_modules\mongoose\lib\schematype.js:1072:12)
[0]         at model.$set (C:\Users\Hp\Desktop\StuPro\backend\node_modules\mongoose\lib\document.js:1228:20)
[0]         at model.set [as mdesc] (C:\Users\Hp\Desktop\StuPro\backend\node_modules\mongoose\lib\helpers\document\compile.js:161:19)
[0]         at C:\Users\Hp\Desktop\StuPro\backend\controllers\blog.js:54:20
[0]         at IncomingForm.<anonymous> (C:\Users\Hp\Desktop\StuPro\backend\node_modules\formidable\lib\incoming_form.js:107:9)
[0]         at IncomingForm.emit (events.js:315:20)
[0]         at IncomingForm._maybeEnd (C:\Users\Hp\Desktop\StuPro\backend\node_modules\formidable\lib\incoming_form.js:557:8)
[0]         at C:\Users\Hp\Desktop\StuPro\backend\node_modules\formidable\lib\incoming_form.js:238:12
[0]         at WriteStream.<anonymous> (C:\Users\Hp\Desktop\StuPro\backend\node_modules\formidable\lib\file.js:79:5)
[0]         at Object.onceWrapper (events.js:421:28)
[0]         at WriteStream.emit (events.js:315:20)
[0]         at finishMaybe (_stream_writable.js:639:14)
[0]         at _stream_writable.js:616:5
[0]         at WriteStream._final (internal/fs/streams.js:367:3)
[0]         at callFinal (_stream_writable.js:609:10) {
[0]       stringValue: '"{\n' +
[0]         '  log: { timeTakenInMilliseconds: 28 },\n' +
[0]         "  result: 'What is Lorem Ipsum? Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the indust',\n" +
[0]         "  ranges: [ [ 0, 4 ], [ 24, 40, ' ' ], [ 51, 61, ' ' ] ],\n" +
[0]         '  allTagLocations: [ [ 0, 4 ], [ 24, 29 ], [ 29, 32 ], [ 32, 40 ], [ 51, 60 ] ],\n' +
[0]         '  filteredTagLocations: [ [ 0, 4 ], [ 24, 29 ], [ 29, 32 ], [ 32, 40 ], [ 51, 60 ] ]\n' +
[0]         '}"',
[0]       messageFormat: undefined,
[0]       kind: 'string',
[0]       value: [Object],
[0]       path: 'mdesc',
[0]       reason: null
[0]     }
[0]   },
[0]   _message: 'Blog validation failed'
[0] }
[0] POST /api/blog 400 1781.542 ms - 12

I read the previous answers to such errors but did not get any help.it may be from BlogSchema so I am providing all the code related to this API,

Blog Schema

const mongoose = require('mongoose');
const { ObjectId } = mongoose.Schema;

const blogSchema = new mongoose.Schema(
    {
        title: {
            type: String,
            trim: true,
            min: 3,
            max: 160,
            required: true
        },
        slug: {
            type: String,
            unique: true,
            index: true
        },
        body: {
            type: {},
            required: true,
            min: 200,
            max: 2000000
        },
        excerpt: {
            type: String,
            max: 1000
        },
        mtitle: {
            type: String
        },
        mdesc: {
            type:String
        },
        photo: {
            data: Buffer,
            contentType: String
        },
        categories: [{ type: ObjectId, ref: 'Category', required: true }],
        tags: [{ type: ObjectId, ref: 'Tag', required: true }],
        postedBy: {
            type: ObjectId,
            ref: 'User'
        }
    },
    { timestamp: true }
);

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

blogCreate controller

const Blog = require('../models/Blog');
const Category = require('../models/Category');
const Tag = require('../models/Tag');
const formidable = require('formidable');
const slugify = require('slugify');
const stripHtml = require('string-strip-html');
const _ = require('lodash');
const { errorHandler } = require('../helpers/dbErrorHandler');
const fs = require('fs');
const { smartTrim } = require('../helpers/blog');

exports.create = (req, res) => {
    let form = new formidable.IncomingForm();
    form.keepExtensions = true;
    form.parse(req, (err, fields, files) => {
        if (err) {
            return res.status(400).json({
                error: 'Image could not upload'
            });
        }

        const { title, body, categories, tags } = fields;

        if (!title || !title.length) {
            return res.status(400).json({
                error: 'title is required'
            });
        }

        if (!body || body.length < 200) {
            return res.status(400).json({
                error: 'Content is too short'
            });
        }

        if (!categories || categories.length === 0) {
            return res.status(400).json({
                error: 'At least one category is required'
            });
        }

        if (!tags || tags.length === 0) {
            return res.status(400).json({
                error: 'At least one tag is required'
            });
        }

        let blog = new Blog();
        blog.title = title;
        blog.body = body;
        blog.excerpt = smartTrim(body, 320, ' ', ' ...');
        blog.slug = slugify(title).toLowerCase();
        blog.mtitle = `${title} | ${process.env.APP_NAME}`;
        blog.mdesc = stripHtml(body.substring(0, 160));
        blog.postedBy = req.user._id;
        // categories and tags
        let arrayOfCategories = categories && categories.split(',');
        let arrayOfTags = tags && tags.split(',');

        if (files.photo) {
            if (files.photo.size > 10000000) {
                return res.status(400).json({
                    error: 'Image should be less then 1mb in size'
                });
            }
            blog.photo.data = fs.readFileSync(files.photo.path);
            blog.photo.contentType = files.photo.type;
        }

        blog.save((err, result) => {
            console.log('Blog create error',err)
            if (err) {
                return res.status(400).json({
                    error: errorHandler(err)
                });
            }
            // res.json(result);
            Blog.findByIdAndUpdate(result._id, { $push: { categories: arrayOfCategories } }, { new: true }).exec(
                (err, result) => {
                    if (err) {
                        return res.status(400).json({
                            error: errorHandler(err)
                        });
                    } else {
                        Blog.findByIdAndUpdate(result._id, { $push: { tags: arrayOfTags } }, { new: true }).exec(
                            (err, result) => {
                                if (err) {
                                    return res.status(400).json({
                                        error: errorHandler(err)
                                    });
                                } else {
                                    res.json(result);
                                }
                            }
                        );
                    }
                }
            );
        });
    });
};

Any help will be appreciated. Thanks!


Solution

  • The solution is very simple to this problem, I have also faced this issue once. According to string-strip-html docs, you have to add result at the end of your stripHtml().

    From: blog.mdesc = stripHtml(body.substring(0, 160));

    To: blog.mdesc = stripHtml(body.substring(0, 160)).result;