title: MEAN stack ng-upload-file
body: <p>I am currently using <strong>MEAN.js</strong> to create an app and I <strong>scaffolded</strong> a simple entity called <strong>Campaign</strong>. I would like each Campaign to have a picture associated. Therefore, I would like to change the <strong>CRUD</strong> interface to be able to <strong>upload a file</strong> to the back end.</p>
  
  <p>I injected the <strong>ng-file-upload</strong> plugin to create the FE with <strong>Angular</strong>. On the <strong>Node.js</strong> side, I installed the multer plugin to help me save the file into a folder (e.g. ./uploads). The thing is that I do not quite get the flow and I was hoping for a suggestion.</p>
  
  <p>Please, find below the view:</p>
  
  <pre><code>&lt;section data-ng-controller="CampaignsController"&gt;
      &lt;div class="page-header"&gt;
          &lt;h1&gt;New Campaign&lt;/h1&gt;
      &lt;/div&gt;
      &lt;div class="col-md-12"&gt;
          &lt;form class="form-horizontal" data-ng-submit="create()" novalidate&gt;
              &lt;fieldset&gt;
                  &lt;div class="form-group"&gt;
                      &lt;label class="control-label" for="name"&gt;Name&lt;/label&gt;
                      &lt;div class="controls"&gt;
                          &lt;input type="text" data-ng-model="name" id="name" class="form-control" placeholder="Name" required&gt;
                      &lt;/div&gt;
                  &lt;/div&gt;
                  &lt;div class="form-group"&gt;
                      &lt;button ng-file-select ng-model="token"&gt;Upload the token&lt;/button&gt;
                      &lt;div ng-file-drop ng-model="token" class="drop-box" 
                          drag-over-class="{accept:'dragover', reject:'dragover-err', delay:100}"
                          accept="image/*"&gt;
                                  Drop image file here
                      &lt;/div&gt;
                      &lt;div ng-no-file-drop&gt;Image drop is not supported for this browser.&lt;/div&gt;
                  &lt;/div&gt;
                  &lt;div class="form-group"&gt;
                      &lt;input type="submit" class="btn btn-default"&gt;
                  &lt;/div&gt;
                  &lt;div data-ng-show="error" class="text-danger"&gt;
                      &lt;strong data-ng-bind="error"&gt;&lt;/strong&gt;
                  &lt;/div&gt;
              &lt;/fieldset&gt;
          &lt;/form&gt;
      &lt;/div&gt;
  &lt;/section&gt;
  </code></pre>
  
  <p>Then, the Angular controller action:</p>
  
  <pre><code>// Create new Campaign
      $scope.create = function() {
          // Create new Campaign object
          var campaign = new Campaigns ({
              name: this.name
          });
  
          $scope.$watch('token', function() {
              $scope.upload = $upload.upload({
                  url: '/campaigns', //upload.php script, node.js route, or servlet url
                  method: 'POST', //Post or Put
                  headers: {'Content-Type': 'multipart/form-data'},
                  //withCredentials: true,
                  data: campaign, //from data to send along with the file
                  file: $scope.token, // or list of files ($files) for html5 only
                  //fileName: 'photo' // to modify the name of the file(s)                
              }).success(function (response, status) {
                  // Redirect after save
                  campaign.$save(function(response) {
                      $location.path('campaigns/' + response._id);
  
                      // Clear form fields
                      $scope.name = '';
                  }, function(errorResponse) {
                      $scope.error = errorResponse.data.message;
                  }); 
              }
              ).error(function (errorResponse) {
                  $scope.error = errorResponse.data;
                  //$scope.error = errorResponse.data.message;
              });
          });
      };
  </code></pre>
  
  <p>Finally, the Node.js controller portion:</p>
  
  <pre><code> var mongoose = require('mongoose'),
          errorHandler = require('./errors'),
          multer = require('multer'),
          Campaign = mongoose.model('Campaign'),
          _ = require('lodash');
  
      /**
       * Create a Campaign
       */
      exports.create = function(req, res) {
          var campaign = new Campaign(req.body);
          campaign.user = req.user;
  
          multer({
              dest: './uploads/'
          });
  
          campaign.save(function(err) {
              if (err) {
                  return res.status(400).send({
                      message: errorHandler.getErrorMessage(err)
                  });
              } else {
                  res.jsonp(campaign);
              }
          });
      };
  </code></pre>
  
  <p>Right now, what happens is that - when I try to upload a file - the uploader does not wait for the file to be selected, but it sends the POST request immediately (why?). Moreover, I get a 400 response.</p>
  
  <p>Any suggestion would be really appreciated!</p>
  
  <p>Thanks
  Cheers</p>