MEAN Stack File uploads MEAN Stack File uploads mongodb mongodb

MEAN Stack File uploads


I recently did something just like this. I used angular-file-upload. You'll also want node-multiparty for your endpoint to parse the form data. Then you could use s3 for uploading the file to s3.

Here's some of my [edited] code.

Angular Template

<button>  Upload <input type="file" ng-file-select="onFileSelect($files)"></button>

Angular Controller

$scope.onFileSelect = function(image) {  $scope.uploadInProgress = true;  $scope.uploadProgress = 0;  if (angular.isArray(image)) {    image = image[0];  }  $scope.upload = $upload.upload({    url: '/api/v1/upload/image',    method: 'POST',    data: {      type: 'profile'    },    file: image  }).progress(function(event) {    $scope.uploadProgress = Math.floor(event.loaded / event.total);    $scope.$apply();  }).success(function(data, status, headers, config) {    AlertService.success('Photo uploaded!');  }).error(function(err) {    $scope.uploadInProgress = false;    AlertService.error('Error uploading file: ' + err.message || err);  });};

Route

var uuid = require('uuid'); // https://github.com/defunctzombie/node-uuidvar multiparty = require('multiparty'); // https://github.com/andrewrk/node-multipartyvar s3 = require('s3'); // https://github.com/andrewrk/node-s3-clientvar s3Client = s3.createClient({  key: '<your_key>',  secret: '<your_secret>',  bucket: '<your_bucket>'});module.exports = function(app) {  app.post('/api/v1/upload/image', function(req, res) {    var form = new multiparty.Form();    form.parse(req, function(err, fields, files) {      var file = files.file[0];      var contentType = file.headers['content-type'];      var extension = file.path.substring(file.path.lastIndexOf('.'));      var destPath = '/' + user.id + '/profile' + '/' + uuid.v4() + extension;      var headers = {        'x-amz-acl': 'public-read',        'Content-Length': file.size,        'Content-Type': contentType      };      var uploader = s3Client.upload(file.path, destPath, headers);      uploader.on('error', function(err) {        //TODO handle this      });      uploader.on('end', function(url) {        //TODO do something with the url        console.log('file opened:', url);      });    });  });}

I changed this from my code, so it may not work out of the box, but hopefully it's helpful!


Recently a new package was added to the list of packages on mean.io. It's a beauty!

Simply run:

$ mean install mean-upload

This installs the package into the node folder but you have access to the directives in your packages.

http://mean.io/#!/packages/53ccd40e56eac633a3eee335

On your form view, add something like this:

    <div class="form-group">        <label class="control-label">Images</label>        <mean-upload file-dest="'/packages/photos/'" upload-file-callback="uploadFileArticleCallback(file)"></mean-upload>        <br>        <ul class="list-group">            <li ng-repeat="image in article.images" class="list-group-item">                {{image.name}}                <span class="glyphicon glyphicon-remove-circle pull-right" ng-click="deletePhoto(image)"></span>            </li>        </ul>    </div>

And in your controller:

    $scope.uploadFileArticleCallback = function(file) {      if (file.type.indexOf('image') !== -1){          $scope.article.images.push({            'size': file.size,            'type': file.type,            'name': file.name,            'src': file.src          });      }      else{          $scope.article.files.push({            'size': file.size,            'type': file.type,            'name': file.name,            'src': file.src          });      }    };    $scope.deletePhoto = function(photo) {        var index = $scope.article.images.indexOf(photo);        $scope.article.images.splice(index, 1);    }

Enjoy!


Mean-upload has been obsoleted and is now called "upload". It is managed in - https://git.mean.io/orit/upload