File Upload with AngularJS, Node and Express

0
149

 

In my Angular App, in the view I added the following code:

                                 Add Logo              
</div>

In the controller for the view I placed the following code:

$scope.uploadLogo = function(logoFile) {
      API.uploadLogo(logoFile).success(function (uploadResponse) {
          // Handle response from server
        console.log(uploadResponse);
      }).error(function (error) {
        // Handle error from server
        console.log(error);
      });
    };

Make sure that in your controller, you declare API. The reason being, we are going to have an API service that will take the code and then hand it over to Express.

Speaking of that API service, that’s what we have right here:

app.('theApp')
.service('API', ['$http', function ($http) {
return {
uploadLogo: function(logo) {
var formData = new FormData();
formData.append("file", logo);
return $http.post('/api/uploads', formData, {
headers: {'Content-Type': undefined},
transformRequest: angular.identity
});
}
};
}]);

This will handle taking the file and then punting it to Express which we will set up below to take the post data and save it to the server:

'use strict';
var express = require('express');
var controller = require('./upload.controller');
var express = require('express');
var multer = require('multer');
var router = module.exports = express.Router();
var fs = require('fs');
router.use(multer({
    dest: './public/uploads',
    changeDest: function(dest, req, res){
        dest += '/haha/';
        try{
            stat = fs.statSync(dest);
        }catch(err){
            fs.mkdirSync(dest);
        }
        return dest;
    },
    onFileUploadStart: function(file){
        console.log('starting');
    }
}));
router.post('/', sendResponse);
function sendResponse(req, res){
res.send('ok');
};
module.exports = router;

What we’re doing here is we have an api endpoint called uploads. When something comes in, it will load ‘multer’ along with some other requirements and then attempt to save the file. The try/catch will check to see if the directory exists, and if it doesn’t it will create it.

You might have noticed the addition to the ‘dest’ variable ‘haha’. That’s a place holder for us to be able to add custom destinations. The plan is to be able to pass a variable to the file upload that will state where the file should be uploaded. It would be very messy to just have everything uploaded directly into uploads.

Finally, it will respond in the affirmative (or negative) depending on how things turn out.

Multer is an important piece of this. It handles the multipart form-data and that’s the magic of transferring the file via the web to the server. So, be sure you get that.

In an upcoming post I’m going to remove the simple form field and use a directive and ng-flow for the angular piece to get a little better UX in the mix.