0

I'm using a form on the client side where the user could upload files, as many as he wants to, and then I send it all over with axios.

Receiving it in NodeJS, I'm using Multer to get the files and its informations with req.files, like that:

[ { fieldname: 'file1',
    originalname: 'someimage.jpg',
    encoding: '7bit',
    mimetype: 'image/jpeg',
    destination: './uploads/',
    filename: '71027041755f49366c132555066d5b89',
    path: 'uploads\\71027041755f49366c132555066d5b89',
    size: 69336 } ]

As we can see, it's a Array, which could contain more than one file, which is nice, but here comes my problem.

I want to store the informations of those files in MongoDB using Mongoose, so that I know how the file is called, its destination, size, etc.

I defined a Schema in Mongoose like that:

const someSchema = new Schema({
  files: {
    originalname: String,
    filename: String,
    mimetype: String,
    size: String,
    destination: String,
    path: String
  }
});

But this would only allow me to store one file information. I also tried earlier with:

const someSchema = new Schema({
  files: Array
});

But this won't work (TypeError: Cannot set property 'originalname' of undefined). I also tried setting Object, which also errors out (TypeError: Cannot read property '0' of undefined).

By the way, I'm reading the "files" with:

 for (let i = 0; i < req.files.length; i++) {
      someschema.files[i].originalname = req.files[i].originalname;
      someschema.files[i].filename = req.files[i].filename;
      someschema.files[i].mimetype = req.files[i].mimetype;
      someschema.files[i].size = req.files[i].size;
      someschema.files[i].destination = req.files[i].destination;
      someschema.files[i].path = req.files[i].path;
    }

Logging every req.files[i].XXX above, everything is defined as it should.

Is there a way to make a schema which accepts multiple "files"?

In other words: Is there a way to make a schema which accepts a Array with multiple Objects, if possible with those exact keys?

Thanks in advance.

EDIT: I came up with files: [Object], but this also won't work (TypeError).

2 Answers 2

1

Use $addToSet to push another object to an array.

You can use $push instead of $addToSet but this will allow you to insert duplicate object.

Schema:

var UserSchema = new Schema({
  files: [{
    originalname: String,
    filename: String,
    mimetype: String,
    size: String,
    destination: String,
    path: String
  }]
});

To insert another object into array.

let obj = {
  originalname: "11",
  filename: "11",
  mimetype: "11",
  size: "11",
  destination: "11",
  path: "11"
}

User.update({
  _id: mongoose.Types.ObjectId("5bd99f95f255307d51f32578")
}, {
    $addToSet: { files: obj}
}).exec(function(err, updated){
  console.log(updated);
})

======== Update =======

Your someschema.files has some lowest length. For eg 2 and you are iterating more than that with i index. Try below:

for (let i = 0; i < req.files.length; i++) {
  let obj = {};
  obj.originalname = req.files[i].originalname;
  obj.filename = req.files[i].filename;
  obj.mimetype = req.files[i].mimetype;
  obj.size = req.files[i].size;
  obj.destination = req.files[i].destination;
  obj.path = req.files[i].path;

  someschema.files.push(obj); // lastly push whole object.
}
Sign up to request clarification or add additional context in comments.

4 Comments

Storing it with req.files[i] this Schema also gives a TypeError: Cannot set property 'originalname' of undefined. I believe my error is writing it with [i] to a Array, but how should it be done?
This is because your someschema.files has some lowest length. For eg 2 and you are iterating more than that with index
It worked. Thank you very much. Also thanks for your explanation on why it hadn't worked before.
@Fusseldieb, My Pleasure.
0

Try to wrap your fields inside []

const someSchema = new Schema({
  files: [{
    originalname: String,
    filename: String,
    mimetype: String,
    size: String,
    destination: String,
    path: String
  }]
});

1 Comment

Thanks for your answer, but this is basically what the other answer also proposed.

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.