12

I am building mock restful API to learn better. I am using MongoDB and node.js, and for testing I use postman.

I have a router that sends update request router.patch. In my DB, I have name (string), price (number) and imageProduct (string - I hold the path of the image).

I can update my name and price objects using raw-format on the postman, but I cannot update it with form-data. As I understand, in raw-form, I update the data using the array format. Is there a way to do it in form-data? The purpose of using form-data, I want to upload a new image because I can update the path of productImage, but I cannot upload a new image public folder. How can I handle it?

Example of updating data in raw form

[ {"propName": "name"}, {"value": "test"}]

router.patch

router.patch('/:productId', checkAuth, (req, res, next) => {
const id = req.params.productId;

const updateOps = {};

for (const ops of req.body) {
    updateOps[ops.propName] = ops.value;
}
Product.updateMany({_id: id}, {$set: updateOps})
    .exec()
    .then(result => {
        res.status(200).json({
            message: 'Product Updated',
            request: {
                type: 'GET',
                url: 'http://localhost:3000/products/' + id
            }
        });
    })
    .catch(err => {
        console.log(err);
        res.status(500).json({
            err: err
        });
    });
});
Kaan Taha Köken
  • 933
  • 3
  • 17
  • 37
  • Hmm `req.body` is not iterable like arrays or maps or arguments so you can't iterate trough it using the `for of` loop, try using `for in` loop for starters: https://stackoverflow.com/questions/29285897/what-is-the-difference-between-for-in-and-for-of-in-javascript – maljukan Sep 04 '18 at 13:05
  • Check out: https://stackoverflow.com/a/26347677/3938031 – Noel Kriegler Sep 04 '18 at 13:07
  • @maljukan actually I can do it in **raw-form** (i gave the example), but I can't do it in **form-data** form. As i understand, i needed to treat as an array – Kaan Taha Köken Sep 04 '18 at 13:08
  • Debug and try what @NoelKriegler proposed, i've forgot it :) – maljukan Sep 04 '18 at 13:10
  • okay, I will check it in a minute. I will let you know – Kaan Taha Köken Sep 04 '18 at 13:11
  • In my app.js file I have body parser and other stuff. I can't do update operation without using **raw-form**. My main question, Is there way to do update with **form-data** type? @NoelKriegler – Kaan Taha Köken Sep 04 '18 at 13:39
  • If you're using Postmon to send requests, make sure to choose `JSON` in the `Body`. The default `Text` wouldn't work and will give out this error. – Upulie Han Oct 21 '20 at 14:51

3 Answers3

21

Using for...of is a great idea, but you can't use it like you are to loop through an object's properties. Thankfully, Javascript has a few new functions that turn 'an object's properties' into an iterable.

Using Object.keys:

const input = {
  firstName: 'Evert',
} 
for (const key of Object.keys(input)) {
  console.log(key, input[key]);
}

You can also use Object.entries to key both the keys and values:

const input = {
  firstName: 'Evert',
} 
for (const [key, value] of Object.entries(input)) {
  console.log(key, value);
}
Evert
  • 93,428
  • 18
  • 118
  • 189
2

I know this answer might be too late to help you but it might help someone in 2020 and beyond.

First, comment out this block:

//const updateOps = {};

//for (const ops of req.body) {
//updateOps[ops.propName] = ops.value;
//}

and change this line:

Product.updateMany({_id: id}, {$set: updateOps})

to this:

Product.updateMany({_id: id}, {$set: req.body})

Everything else is fine. I was having similar issues, but this link helped me: [What is the difference between ( for... in ) and ( for... of ) statements in JavaScript?

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Sage Hassan
  • 31
  • 2
  • 8
0

To handle multi-part form data, the bodyParser.urlencoded() or app.use(bodyParser.json());body parser will not work.

See the suggested modules here for parsing multipart bodies.

You would be required to use multer in that case

 var bodyParser = require('body-parser');
 var multer = require('multer');
 var upload = multer();

// for parsing application/json
app.use(bodyParser.json()); 

// for parsing application/xwww-
app.use(bodyParser.urlencoded({ extended: true })); 
//form-urlencoded

// for parsing multipart/form-data
app.use(upload.array()); 
app.use(express.static('public'));
Santosh
  • 3,477
  • 5
  • 37
  • 75