0
votes

I have a manufacturer schema in mongoose with some data stored in mongo. My goal is to be able to edit a manufacturer's name via a form. But I get the following error when changing the name and clicking submit.

Manufacturer validation failed: _id: Cast to String failed for value "[ 'example', 'example edited' ]" at path "_id"

I understand that there is some sort of conflict with _id, as it is automatically created by mongo. But in this case I am required to use _id for the object name.

Here is my mongoose schema

var manufacturerSchema    = mongoose.Schema({
    // The _id property serves as the primary key. If you don't include it
    // the it is added automatically. However, you can add it in if you
    // want to manually include it when creating an object.

    // _id property is created by default when data is inserted.
    _id:            {"type" : String},
    mfgDiscount:   {"type" : Number}
}, 
{   // Include this to eliminate the __v attribute which otherwise gets added
    // by default.
    versionKey: false 
});

Here is the update

async update(editedObj) {   

        // Load the corresponding object in the database.
        let manufacturerObj = await this.getManufacturer(editedObj.id);

        // Check if manufacturer exists.
        if(manufacturerObj) {

            // Manufacturer exists so update it.
            let updated = await Manufacturer.updateOne(

                // Set new attribute values here.
                {$set: { _id: editedObj._id }}); 

            // No errors during update.
            if(updated.nModified!=0) {
                response.obj = editedObj;
                return response;
            }

Update function

// Receives posted data that is used to update the item.
exports.Update = async function(request, response) {
let manufacturerID = request.body._id;
console.log("The posted manufacturer id is: " + manufacturerID);

// Parcel up data in a 'Manufacturer' object.
let tempManufacturerObj  = new Manufacturer( {
    _id: manufacturerID,
    id:    request.body._id,
});

// Call update() function in repository with the object.
let responseObject = await _manufacturerRepo.update(tempManufacturerObj);

// Update was successful. Show detail page with updated object.
if(responseObject.errorMessage == "") {
    response.render('Manufacturer/Detail', { manufacturer:responseObject.obj, 
                                        errorMessage:"" });
}

// Update not successful. Show edit form again.
else {
    response.render('Manufacturer/Edit', { 
        manufacturer:      responseObject.obj, 
        errorMessage: responseObject.errorMessage });
}
};

and here is the form

<% layout('../layouts/mainlayout.ejs') -%>

<form action="/Manufacturer/Update" method="POST">

<input type='hidden' name="_id" value= <%= manufacturer._id %> /> <br/>
<input type='text'  name="_id" 
   value="<%= manufacturer._id ? manufacturer._id : '' %>"  /><br/>
   <input type="submit" value="Submit">
</form>
<%= errorMessage %>
1
From the error message it looks like it's trying to cast an array with 2 elements: 'example' and 'example edited' into a string. Any idea where those values are coming from?Darren G
I actually modified the array objects to make it more clear. The first object is always the first part of the manufacturer's name, and the second one is when edited. so let's say if a manufacturer's name is dole bananas and I edit it as dole oranges it outputs the error with the array ['dole', 'dole oranges']A Banitaba

1 Answers

0
votes

I haven't tested this out, but _id is not a string in mongodb, it's a special data type, I don't remember the name. So when you try to cast it as a string something gets upset and throws an error. In the apps I wrote (lots of cut and paste of course) I never defined _id so didn't run into any problems.

I think if you take _id out of the schema you are going to get what you want.

If you want to make manufacturer.id the primary key, then you have to say that explicitly and don't call it _id

I would add a name field to the manufacturer schema. You could either make that the primary key or create an index on the name to speed up access