0

I'm working with the following schema, I've only shown the relevant parts here:

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;
    var punchSchema = new Schema({punch: Date});
/**
 * Child Schema
 */
var ChildSchema = new Schema({
    punchesIn: [punchSchema]
});

mongoose.model('Child', ChildSchema);

And what I am trying to accomplish is to be able to take a Child Document, and update the punchesIn field from a javascript array. So if I had:

Child1{
    _id: XYZ
    punchesIn: [Date1, Date2, Date3]
}

jsArray = [Date4, Date2, Date5]

I would be able to run an update and Child1 would become:

Child1{
    _id: XYZ
    punchesIn: [Date4, Date2, Date5]
}

Here is a dumbed down version of what I attempted, there are no syntax errors with the actual implementation, this is just for show:

Child.findById(XYZ, function(err, child) {
    var query = {'_id': XYZ };
    var update = {  $set: {
                        punchesIn: jsArray
                    },
                 };
    var options = { new: true };
    Child.findOneAndUpdate(query, update, options, function(err, child) {
        if (err) {
            console.log('got an error');
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        }
    });

Running this code, which I know works for non array fields in a document, results in the following error:

500 TypeError: Cannot use 'in' operator to search for '_id' in punchesIn

From what I can gather, this is because punchesIn is of the type MongooseDocumentArray, and jsArray is just a a javascript array.

Would it be possible to run some kind of loop that would create a MongooseDocumentArray where the different fields are document versions of the Dates found in the jsArray?

1 Answer 1

1

You'll need to convert your javascript array to an array of Punch model instances since that's what the Child schema expects. Here's a function that does it:

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/test');

var punchSchema = new Schema({punch: Date});

var childSchema = new Schema({
    punchesIn: [punchSchema]
});

var Child = mongoose.model('Child', childSchema);
var Punch = mongoose.model('Punch', punchSchema);

function createPunchList(inArr){
    var outArr = [];
    for (var i=0;i<inArr.length;i++){
        var punch = new Punch({
           date: inArr[i]
        });
        outArr.push(punch);
    }
    return outArr;
}

//test data
for (var i=0;i<10;i++){
    var newChild = new Child({
       punchesIn: createPunchList([new Date(), new Date(), new Date()])
    });

    newChild.save();
}

Child.find({}, function(err, c){
    console.log(c);
});
Sign up to request clarification or add additional context in comments.

3 Comments

So I tried to take what you had written up for my simplified example and adapt it to my project, and its not quite functional. Here's a quick code snippet: i.imgur.com/B2vfqFr.png But at line outArr.push... The value of punch doesn't contain the punch field, seen here: i.imgur.com/JyHFjCT.png Any idea why the punch wouldn't be constructing correctly? I thought it might have something to do with the formatting of new Date(), but didn't get any where with that. Here's my server model containing the schemas, if that helps: i.imgur.com/0lXLfhM.png
The property declared on your punch schema is punch instead of date.
Yup, that would be the problem, don't know why I didn't catch that. Thanks so much, its fully working!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.