4

Situation

I implemented file uploading. Front-end code is taken from popular tutorial. I send POST in service:

myApp.service('fileUpload', ['$http', function ($http) {
    this.uploadFileToUrl = function(file, uploadUrl){
        var fd = new FormData();
        fd.append('file', file);
        
        $http.post(uploadUrl, fd, {
             transformRequest: angular.identity,
             headers: {'Content-Type': undefined}
        })
        
        .success(function(){
        })
       
        .error(function(){
         });
        }
    }]);

Typical multer usage in back-end:

exports.postFile = function (req, res) {

    var storage = multer.diskStorage({ //multers disk storage settings
        destination: function (req, file, cb) {
            cb(null, '../documents/')
        },
        filename: function (req, file, cb) {
            cb(null, file.originalname)
        }
    });

    var upload = multer({ //multer settings
        storage: storage
    }).single('file');

    upload(req, res, function (err) {
        if (err) {
            res.json({error_code: 1, err_desc: err});
            return;
        }
        res.json({error_code: 0, err_desc: null});
    })

};

That works.

Question

How to send some data in the same POST, let say string "additional info"?

What I tried

I tried to add data in service, i.e.:

...
var fd = new FormData();
fd.append('file', file);
fd.append('model', 'additional info');

$http.post(uploadUrl, fd, {...})

It seems to be sent, but I don't know how to receive it in back-end. Tried to find it in req (without success).

3 Answers 3

6

To send data (i.e. json) and file in one POST request add both to form data:

myApp.service('fileUpload', ['$http', function ($http) {
    this.uploadFileToUrl = function(file, uploadUrl){
        var fd = new FormData();
        fd.append('file', file);

        var info = {
            "text":"additional info"
        };
        fd.append('data', angular.toJson(info));

        $http.post(uploadUrl, fd, {
             transformRequest: angular.identity,
             headers: {'Content-Type': undefined}
        })

        .success(function(){
        })

        .error(function(){
        });
    }
}]);

On server side it's in req.body.data, so it can be received i.e. like this:

upload(req, res, function (err) {
    if (err) {
        res.json({error_code: 1, err_desc: err});
        return;
    }

    console.log(req.body.data);

    res.json({error_code: 0, err_desc: null});
})
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for this helpful answer. solved my problem.
0

You can get the file from req.files and save it with fs.writeFile.

fs.readFile(req.files.formInput.path, function (err, data) {
  fs.writeFile(newPath, data, function (err) {
    if (err) {
    throw err;
    }
    console.log("File Uploaded");
  });
});

3 Comments

I don't have any problems with sending end receiving files. It works. I want to send (and receive) additional data (along with file) in the same POST request.
You can use the data property in your $http.post to send an object with all additional data that you want, sending all inputs.
i have modified the first answer showing how to pass data from all inputs, assuming you have a ng-model="user.email" etc on your input file.
-1

You can do something like this:

          $http({
                url: url, 
                method: 'POST',
                data: json_data,
                headers: {'Content-Type': 'application/json'}
          }).then(function(response) {
                var res = response.data;
                console.log(res);
          }, function errorCallback(response) {
              // called asynchronously if an error occurs
             // or server returns response with an error status.
          });

Or just add the data property to your function.

    var userObject = {
    email: $scope.user.email,
    password: $scope.user.password,
    fullName: $scope.user.fullName
    };

    $http.post(uploadUrl, fd, {
         transformRequest: angular.identity,
         data: userObject,
         headers: {'Content-Type': 'application/json'}
    })

You can try something like this on the backend.

req.on('data', function (chunk) {
    console.log(chunk);
});

5 Comments

Where is file in this POST?
You said some string data.
I mean string along with file, as title says.
Regarding last edit: why should I look for it in server response?
Sorry. Is req.on. I will change that. Take a look at the second answer. Hope this help!

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.