Cacos Cacos - 1 year ago 113
AngularJS Question

MEAN Stack File uploads

I've recently started programming with the MEAN Stack, and I'm currently implementing some sort of social network. Been using the framework to do so.
My main problem right now is getting the file upload to work, because what I want to do is receive the file from the form into the AngularJS Controller and pass it along with more info's to ExpressJS so I can finally send everything to MongoDB. (I'm building a register new user form).

I dont want to store the file itself on the database but I want to store a link to it.

I've searched dozens of pages on google with different search queries but I couldn't find anything that I could understand or worked. Been searching for hours to no result. That's why I've came here.

Can anyone help me with this?

Thanks :)

EDIT: Maybe a bit of the code would help understand.

The default Users Angular controller which I'm using as foundation has this:

$scope.register = function(){
$scope.usernameError = null;
$scope.registerError = null;
$'/register', {
email: $,
password: $scope.user.password,
confirmPassword: $scope.user.confirmPassword,
username: $scope.user.username,
name: $scope.user.fullname
})//... has a bit more code but I cut it because the post is the main thing here.

What I want to do is:
Receive a file from a form, onto this controller and pass it along with email, password, name, etc, etc and be able to use the json on expressjs, which sits on the server side.
The '/register' is a nodejs route so a server controller which creates the user (with the user schema) and sends it to the MongoDB.

Answer Source

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

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

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 /;
  }).success(function(data, status, headers, config) {
    AlertService.success('Photo uploaded!');
  }).error(function(err) {
    $scope.uploadInProgress = false;
    AlertService.error('Error uploading file: ' + err.message || err);


var uuid = require('uuid'); //
var multiparty = require('multiparty'); //
var s3 = require('s3'); //

var s3Client = s3.createClient({
  key: '<your_key>',
  secret: '<your_secret>',
  bucket: '<your_bucket>'

module.exports = function(app) {'/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 = '/' + + '/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!