0

I am using Alamofire to send multipart data to my Nodejs and Express API. I am using Multer to upload an image file and some text parameters. For some reason, I am able to upload the image file, but I am unable to send text, such as "title", "price", and "description" - which is probably why I continue to receive a 500 error code when I try to upload from Swift app. I am not sure what the issue is. What am I doing wrong? Here is my Express route:

var multer = require('multer');
var upload = multer({ dest: 'public/uploads/'})

var app = express();

app.use(function(err, req, res, next) {
    console.log(err);
    next(err);
});

var server = app.listen(3000, () => {
  console.log('listening on *:3000');
});


app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
});

// get request params
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());


// log to console
app.use(morgan('dev'));


app.use(express.static('public'));


// use passport package in app
app.use(passport.initialize());
app.use(passport.session());


app.use(multer({dest:'./uploads/'}).single('images'));


/*
app.get('/', function(req, res) {
  res.send('Hello! Welcome to the land of dragons!');
})
*/


// pass passport for config
require('./config/passport')(passport);




// create new product
app.post('/newproduct', upload.single('images'), function (req, res) {

   if (req.body.title == '' || req.body.price == '') {
    res.json({success: false, msg: 'Please add title and price.'});
    console.log('title: ' + req.body.title);
    console.log('price: ' + req.body.price);
  } else {

    var newProduct = new Product({
     title: req.body.title,
     price: req.body.price,
     description: req.body.description,
     images: req.file

    });


    console.log(req.body);
    console.log(req.file);

    // save the new product
    newProduct.save(function(err) {
      if (err) {
       res.json({success: false, msg: 'Listing was unsuccessful.'});
      } else {
       res.json({success: true, msg: 'Successful creating a new product!'});
       console.log(newProduct.createdAt);
       console.log(newProduct.updatedAt);
      }

    });

  }

});

When I try to make a POST request in Postman, it gives me the error msg "Listing was unsuccessful." because a title and price is required to save the object.

And this is what I get in my Terminal:

    {}
{ fieldname: 'images',
  originalname: 'Screen Shot 2016-07-27 at 2.48.14 PM.png',
  encoding: '7bit',
  mimetype: 'image/png',
  destination: './uploads/',
  filename: 'b3247d2b48591c1d6e47f5413647979b',
  path: 'uploads/b3247d2b48591c1d6e47f5413647979b',
  size: 285034 }
POST /newproduct 200 14.081 ms - 51

And when I try make a POST request in my iOS simulator, I get this error:

  Error Domain=com.alamofire.error Code=-6003 
    "Response status code was unacceptable: 500" 
UserInfo={StatusCode=500, NSLocalizedFailureReason=Response status code was unacceptable: 500}

I read that the 500 error code is most likely a server-side issue, but just to be sure - here is my Swift code:

let url = "http://localhost:3000/newproduct"


    Alamofire.upload(.POST, url, multipartFormData: { multipartFormData in

        let image: UIImage = self.productImage.image!

            if let imageData = UIImagePNGRepresentation(image) {
                multipartFormData.appendBodyPart(data: imageData, name: "file", fileName: "fileName.png", mimeType: "image/png")
                multipartFormData.appendBodyPart(data: self.titleLabel.text!.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"title")
                multipartFormData.appendBodyPart(data: self.descriptionLabel.text!.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"description")
                multipartFormData.appendBodyPart(data: self.priceLabel.text!.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"price")
        }

        }, encodingCompletion: { encodingResult in

            switch encodingResult {
            case .Success(let upload, _, _):
                upload.validate()
                upload.responseJSON { response in

                    switch response.result {
                    case .Success:
                        print("success")




                    case .Failure(let error):
                        print(error)
                    }

                }
            case .Failure(let encodingError):
                print(encodingError)
            }

    })

I referred to this post on Stackoverflow as well.

If you need anymore details, please let me know. My API is a large file, so I did not want to upload everything.

Community
  • 1
  • 1
V1P3R
  • 176
  • 3
  • 16
  • FWIW you have two multer middleware being used, one for all routes and one specifically for the `/newproduct` POST route only. Only one should be necessary here, especially since they are both equivalent in what the type of middleware (`.single('images')`). – mscdex Jul 27 '16 at 22:49
  • I commented out app.use(multer({dest:'./uploads/'}).single('images')); ... but now my image file does not upload. :( – V1P3R Jul 27 '16 at 23:01
  • It worked for the first two posts, and requests but after that - req.file returns "undefined". – V1P3R Jul 27 '16 at 23:11
  • Okay, I take that back. Postman was acting buggy. I'm receiving code 200, however, it returns "Listing was unsuccessful" - so it doesn't save the object. – V1P3R Jul 27 '16 at 23:14
  • 1
    Also your name in your Swift code is different for the file field. It is `'file'`and not `'images'`. – mscdex Jul 28 '16 at 02:19
  • @mscdex yoooo, I swear I love you. That totally worked! – V1P3R Jul 28 '16 at 03:00

0 Answers0