1

I'm currently trying to read the days of absence of my colleague from our excel files and store them in a mongodb using mongoose and express-js.

Reading the data works fine, but updating the data in the db always produces the strange behavior, where inserting an Object into an array using Array.push() results in an Array of Objects containing a single object inside the outer array.

The function below gets the raw data from the excel files and attempts to store them in the db. Please ignore the code-mess, I was just prototyping ;-)

function getDaysOff( data, callback )
{
    Member.find({}, function( err, docs ) {
        if ( err )
        {
            console.error( err );
            return [];
        }
        console.log( "found " + docs.length + " team members" );
        docs.forEach( function( element ) {
            // reset all arrays befor continuing
            element.days_of_absence = [];
        } );
        data.forEach( function( element ) {
            for ( let i = 0; i < element.length; ++i )
            {
                var member = element[i];
                for ( let j = 0; j < docs.length; ++j )
                {   
                    if ( member.name.match( new RegExp( docs[j].name, 'g' ) ) )
                    {
                        console.log( member.name + " is " + docs[j].name );
                        for ( let k = 0;  k < member.absent.length; ++k )
                        {
                            docs[j].days_of_absence.push( member.absent[k] );
                            console.log( JSON.stringify( member.absent[k] ) );
                        }
                        console.log( JSON.stringify( docs[j].days_of_absence ) );
                        break;
                    }
                }
            }
        } );
        docs.forEach( function( element ) {
            element.save();
        } );
        callback( docs );
    });
}

And here is the Member schema:

var mongoose = require('mongoose')  
var MemberSchema = new mongoose.Schema(
    {
            _id: {
                        type: 'ObjectId'
                    },
            name: {
                        type: 'String'
                    },
            prename: {
                        type: 'String'
                    },
            days_of_absence: {
                        type: 'Array'
                    }
    }
);
module.exports =  mongoose.model('Member', MemberSchema, 'members');

When printing days_of_absence it yields something like this:

[
  [ { "date": "2018-01-28T23:00:00.000Z", "reason": "P" } ],
  [ { "date": "2018-01-29T23:00:00.000Z", "reason": "P" } ],
  ...
  [ { "date": "2018-09-27T22:00:00.000Z", "reason": "P" } ]
]

Where members.absent[k] is equal to the objects inside the inner array. (I already checked that). However I have no clue where the arrays around the objects come from. What am I missing? What I want is some like this:

[
  { "date": "2018-01-28T23:00:00.000Z", "reason": "P" },
  { "date": "2018-01-29T23:00:00.000Z", "reason": "P" },
  ...
  { "date": "2018-09-27T22:00:00.000Z", "reason": "P" }
]

UPDATE

As suggested I already tested if member.absent[k] is an array however printing it in the loop revealed that it isn't. console.log( member.absent[k] ) yields the desired:

{"date":"2018-09-02T22:00:00.000Z","reason":"P"}
12
  • 2
    member.absent[k] must be an array then. Commented Jul 11, 2018 at 12:40
  • for ( let k = 0; k < member.absent.length; ++k ) why are you skipping the first entry? (++k instead of k++) Commented Jul 11, 2018 at 12:41
  • @connexo I didn't know that ++k would skip the first entry. Coming from C++ it's just a natural thing to use pre increment over post increment. Commented Jul 11, 2018 at 13:00
  • @connexo, the for loop does not rely on post or pre fix at the incremention part. the start and condition part is right, so the array should loop from zero to lenght - 1. Commented Jul 11, 2018 at 13:05
  • @NinaScholz Can you add reference for that? Thanks for correcting me. For the sake of readability and to avoid false conclusions like mine, I'd still recommend to use k++ over ++k. Commented Jul 11, 2018 at 13:11

1 Answer 1

2

It looks like, you have an array for member.absent[k]. You could spread it and get a single object.

docs[j].days_of_absence.push(...member.absent[k]);

I you do not know if the value is always an array, you could make one and spread it.

docs[j].days_of_absence.push(...(
    Array.isArray(member.absent[k])
        ? member.absent[k]
        : [member.absent[k]]
));
Sign up to request clarification or add additional context in comments.

4 Comments

+1 - just make sure member.absent[k] is indeed an array in all cases, otherwise you'll get an error
@Adelin An object would work, too. docs[j].days_of_absence.push({...member.absent[k]});
However, (have a look at my Edit) member.absent[k] ain't no array. That's why i can't understand where the error comes from.
@muXXmit2X, that's quite interesting. somehow do you get an extra array.

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.