简体   繁体   中英

angularjs and ng-file-upload - multiple file upload with multiple ngf-select inputs

BACKGROUND:

I have a form where two files can be uploaded to the server along with a Javascript object literal that is created in another form.

Its optional for these files to be uploaded so there could be none, one or two but the Javascript object literal is always required.

The form is working and the files are being uploaded either as none, one or two along with the Javascript object literal.

QUESTION:

The problem i have is in capturing the response and taking actions based on it. The progress events seem to be captured correctly but it looks like the response object is not which may be a side effect of the way i am using the ng-file-upload or it could just be that the server side is not returning back a proper response object.

Can someone confirm the usage is ok?

I have tried adding .error() and .success() to the Upload.upload call but it says Upload.upload(...).then(...).error is not a function or Upload.upload(...).then(...).success is not a function

SOURCE CODE:

This is just a POC so not production code.

Controller

(function () {
  'use strict';

  angular
    .module('transcend.kyc.signup')
    .controller('SignupFileUpload', SignupFileUpload);

    SignupFileUpload.$inject = ['$scope','Upload', '$log', '$timeout','$location','URLS','SignupService','usSpinnerService','$anchorScroll'];

    function SignupFileUpload($scope, Upload, $log, $timeout, $location, URLS, SignupService,usSpinnerService,$anchorScroll) {
      $log.debug('ENTERING SIGNUP UPLOAD CONTROLLER %s', JSON.stringify(this));

      var params = $location.search();
      var customerInfo = SignupService.getCustomerInfo();
      var uploadData = {};

      $log.debug('CUSTOMER INFO'+JSON.stringify(customerInfo));

      if (typeof Object.keys(customerInfo)[0] === 'undefined') {
        $log.debug('SIGNUP - Must provide customerInfo');
        $location.path('/signup');
      }

      $scope.mobileUpload = function(form) {
        usSpinnerService.spin('spinner');
        $log.debug('Starting Mobile Upload Process to resource - ' + URLS.BASE + URLS.FILE_UPLOAD);
        $log.debug('No Files are uploaded for mobile client');
        $log.debug('Adding customerInfoPart to uploadData');
        uploadData.customerInfoPart = Upload.jsonBlob(customerInfo);
        $log.debug('Upload data - ' + JSON.stringify(uploadData));
        $log.debug('Uploading data');

        Upload.upload({
          url: URLS.BASE + URLS.FILE_UPLOAD,
          data: uploadData
        }).then(function (response) {
          // file is uploaded successfully
          usSpinnerService.stop('spinner');
          $log.debug('Mobile Upload Status - ' + response.status);
          $timeout(function () {
              $scope.serverMessage = response.data;
          });
          if (response.status===204) {
            $location.path('/signup-confirmation');
            SignupService.setCustomerSignupStatus(true);
          } 
        }, function (response) {
          // handle error
          $log.debug('Signup failed with status ' + response.status);
          handleError(response);
        }, function (evt) {
          $scope.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
          $log.debug('Mobile Upload progress ' + $scope.progress);
        });
      };

      $scope.uploadFiles = function(idFile,addressFile,form) {
        usSpinnerService.spin('spinner');

        $log.debug('Starting Upload Process to resource - ' + URLS.BASE + URLS.FILE_UPLOAD);

        $log.debug('Checking for files to upload');
        if (idFile) {
          $log.debug('idFile found, adding to uploadData');
          uploadData.idDocument = idFile;
        }
        if (addressFile) {
          $log.debug('addressFile found, adding to uploadData');
          uploadData.addressDocument = addressFile;
        }

        $log.debug('Adding customerInfoPart to uploadData');
        uploadData.customerInfoPart = Upload.jsonBlob(customerInfo);

        $log.debug('Upload data - ' + JSON.stringify(uploadData));

        $log.debug('Uploading data');

        Upload.upload({
          url: URLS.BASE + URLS.FILE_UPLOAD,
          data: uploadData
        }).then(function (response) {
          // file is uploaded successfully
          usSpinnerService.stop('spinner');
          $log.debug('Upload Status - ' + response.status);

          $timeout(function () {
              $scope.serverMessage = response.data;
          });

          if (response.status===204) {
            $location.path('/signup-confirmation');
            SignupService.setCustomerSignupStatus(true);
          } 
        }, function (response) {
          // handle error
          $log.debug('Signup failed with status ' + response.status);
          handleError(response);

        }, function (evt) {
          // progress notify
          $scope.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
          $log.debug('Upload progress ' + $scope.progress);
        });
      };

      function handleError(error) {
          usSpinnerService.stop('spinner');
          scrollToServerMessage();
          $scope.serverMessage = 'Signup failed with status ' + error.status;
      }

      function scrollToServerMessage() {
          var old = $location.hash();
          $location.hash('serverMessage');
          $anchorScroll();
          //reset to old to keep any additional routing logic from kicking in
          $location.hash(old);
      }
    }
}());

HTML

        <form name="signupForm">
      <div class="panel panel-default no-bottom-margin">
        <div class="hidden-md hidden-lg">
          <div class="panel-heading no-border">
              <h2 class="panel-title" translate>ID Documents</h2>
              <hr/>
          </div>
          <div class="panel-body">
              <span><p>Document upload facility is not supported on mobile devices. Please send your ID documents to <a href="mailto:someone@somewhere.com" target="_top"><span>someone@somwehere.com</span></a> after you complete sign up.</p>
              <p>You will need to scan and upload the following two documents:<br/> 
              - Proof of identity (passport or ID card)<br/>
              - Proof of address (utility bill, bank statement or government issued letter within the last 3 months)</p></span>
          </div>
          <div class="panel-footer">
            <div class="align-right">
                <button type="button"
                        id="proceedBtn"
                        ng-click="mobileUpload(signupForm)" class="btn btn-sm xs-display-block"
                        translate>Complete Sign up
                </button>
            </div>
          </div>
        </div>
        <div class="hidden-xs hidden-sm">
          <div class="form-control-wrapper">
            <div class="panel-heading no-border">
                <h2 class="panel-title" translate>ID Documents</h2>
                <hr/>
                <p>Please upload a copy of your passport, drivers license, or any other government issued identification</p>
            </div>
            <div class="panel-body">
              <div ng-class="{'has-error': signupForm.idfile.$invalid && signupForm.idfile.$dirty,
                            'has-success': signupForm.idfile.$valid}">
                <div  class="btn btn-sm btn-primary"
                      ngf-select=""
                      ngf-max-size="2MB" 
                      ng-model="idFile" 
                      accept="image/*,application/pdf"  
                      ngf-pattern="'image/*,application/pdf'"
                      required="false"
                      id="idfile"
                      name="idfile"><span ng-if="signupForm.idfile.$valid">Change file</span><span ng-if="!signupForm.idfile.$valid">Add file</span>
                </div>  
                <div class="form-group has-error has-feedback" ng-show="signupForm.idfile.$error.maxSize">
                  <span class="input-status placement-left">File is too large, maximum size is 2MB</span>
                </div>
                <div ng-show="signupForm.idfile.$valid" class="form-control-wrapper">
                  <img ngf-thumbnail="idFile" class="thumb"/>
                  <div class="align-right">
                    <button ng-click="idFile = null" ng-show="idFile" class="btn btn-sm btn-warning">Remove</button>
                  </div>
                </div>          
              </div>
            </div>
            <div class="panel-heading no-border">
                <h2 class="panel-title" translate>Proof of address</h2>
                <hr/>
                <p>Please upload a copy of a utility bill or your driving licence</p>
            </div>
            <div class="panel-body">    
              <div ng-class="{'has-error': signupForm.addressfile.$invalid && signupForm.addressfile.$dirty,
                            'has-success': signupForm.addressfile.$valid}">
                <div  class="btn btn-sm btn-primary"
                      ngf-select=""
                      ngf-max-size="2MB" 
                      ng-model="addressFile" 
                      accept="image/*,application/pdf"  
                      ngf-pattern="'image/*,application/pdf'"
                      required="false"
                      id="addressfile"
                      name="addressfile"><span ng-if="signupForm.addressfile.$valid">Change file</span><span ng-if="!signupForm.addressfile.$valid">Add file</span>
                </div>
                <div class="form-group has-error has-feedback" ng-show="signupForm.addressfile.$error.maxSize">
                  <span class="input-status placement-left">File is too large, max size is 2 MB</span>
                </div>
                <div ng-show="signupForm.addressfile.$valid" class="form-control-wrapper">
                  <img ngf-thumbnail="addressFile" class="thumb"/>
                  <div class="align-right">
                    <button ng-click="addressFile = null" ng-show="addressFile" class="btn btn-sm btn-warning">Remove</button>
                  </div>
                </div>
              </div>
            </div>
            <div class="panel-footer">
              <div class="align-right">
                  <button type="button"
                          id="proceedBtn"
                          ng-click="uploadFiles(idFile,addressFile,signupForm)" 
                          class="btn btn-primary"
                          translate>Complete Sign up
                  </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </form>

CONSOLE:

1 - No files attached Only Javascript object literal:

2015-11-16 14:29:43.760 angular.js:11706 Starting Upload Process to resource - http://poc.services.co.uk/v1/customers/signup
2015-11-16 14:29:43.760 angular.js:11706 Checking for files to upload
2015-11-16 14:29:43.761 angular.js:11706 Adding customerInfoPart to uploadData
2015-11-16 14:29:43.762 angular.js:11706 Upload data - {"customerInfoPart":{"_ngfBlob":true}}
2015-11-16 14:29:43.762 angular.js:11706 Uploading data
2015-11-16 14:29:43.763 angular.js:11706 SESSSION INJECTOR Credentials 409f3c71-3936-48f9-ad71-fee11d9077c9
2015-11-16 14:29:44.025 angular.js:11706 Upload progress 100
2015-11-16 14:29:44.025 angular.js:11706 Upload progress 100
2015-11-16 14:29:45.611 angular.js:11706 Upload Status - 204  

2 - Two files attached with Javascript object literal

2015-11-16 14:36:51.845 angular.js:11706 Starting Upload Process to resource - http://poc.services.co.uk/v1/customers/signup
2015-11-16 14:36:51.845 angular.js:11706 Checking for files to upload
2015-11-16 14:36:51.845 angular.js:11706 idFile found, adding to uploadData
2015-11-16 14:36:51.845 angular.js:11706 addressFile found, adding to uploadData
2015-11-16 14:36:51.845 angular.js:11706 Adding customerInfoPart to uploadData
2015-11-16 14:36:51.848 angular.js:11706 Upload data - {"idDocument":{"$ngfDataUrl":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAACegAAAGUCAYAAABEc1DzAAAMFmlDQ…EJSEACEpCABCQgAQlIQAISkIAEJCABCUhAAhKQgATWMYH/B2nQc4eYA6LeAAAAAElFTkSuQmCC"},"addressDocument":{"$ngfDataUrl":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAACc4AAAKYCAYAAABAGvmCAAAMFmlDQ…ABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABJ/B/U81Hrz5c8Q0AAAAASUVORK5CYII="},"customerInfoPart":{"_ngfBlob":true}}
2015-11-16 14:36:51.858 angular.js:11706 Uploading data
2015-11-16 14:36:51.864 angular.js:11706 SESSSION INJECTOR Credentials 409f3c71-3936-48f9-ad71-fee11d9077c9
2015-11-16 14:36:52.142 angular.js:11706 Upload progress 38
2015-11-16 14:36:52.342 angular.js:11706 Upload progress 42
2015-11-16 14:36:52.441 angular.js:11706 Upload progress 46
2015-11-16 14:36:52.542 angular.js:11706 Upload progress 50
2015-11-16 14:36:52.642 angular.js:11706 Upload progress 59
2015-11-16 14:36:52.741 angular.js:11706 Upload progress 63
2015-11-16 14:36:52.843 angular.js:11706 Upload progress 71
2015-11-16 14:36:52.942 angular.js:11706 Upload progress 76
2015-11-16 14:36:53.043 angular.js:11706 Upload progress 84
2015-11-16 14:36:53.143 angular.js:11706 Upload progress 88
2015-11-16 14:36:53.243 angular.js:11706 Upload progress 97
2015-11-16 14:36:53.344 angular.js:11706 Upload progress 100
2015-11-16 14:36:53.344 angular.js:11706 Upload progress 100 Upload data - 

3 - One file attached with Javascript object literal

2015-11-16 14:40:54.263 angular.js:11706 Starting Upload Process to resource - http://poc.services.co.uk/v1/customers/signup
2015-11-16 14:40:54.263 angular.js:11706 Checking for files to upload
2015-11-16 14:40:54.263 angular.js:11706 idFile found, adding to uploadData
2015-11-16 14:40:54.264 angular.js:11706 Adding customerInfoPart to uploadData
2015-11-16 14:40:54.265 angular.js:11706 Upload data - {"idDocument":{"$ngfDataUrl":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAACegAAAGUCAYAAABEc1DzAAAMFmlDQ…EJSEACEpCABCQgAQlIQAISkIAEJCABCUhAAhKQgATWMYH/B2nQc4eYA6LeAAAAAElFTkSuQmCC"},"customerInfoPart":{"_ngfBlob":true}}
2015-11-16 14:40:54.271 angular.js:11706 Uploading data
2015-11-16 14:40:54.272 angular.js:11706 SESSSION INJECTOR Credentials 409f3c71-3936-48f9-ad71-fee11d9077c9
2015-11-16 14:40:54.536 angular.js:11706 Upload progress 64
2015-11-16 14:40:54.736 angular.js:11706 Upload progress 71
2015-11-16 14:40:54.836 angular.js:11706 Upload progress 78
2015-11-16 14:40:54.937 angular.js:11706 Upload progress 92
2015-11-16 14:40:55.037 angular.js:11706 Upload progress 99
2015-11-16 14:40:55.138 angular.js:11706 Upload progress 100
2015-11-16 14:40:55.138 angular.js:11706 Upload progress 100

4 - Single File with Javascript literal object and trying .error()

2015-11-16 15:55:59.111 angular.js:11706 Starting Upload Process to resource - http://epconnect.devtest.aspone.co.uk/v1/customers/signup
2015-11-16 15:55:59.111 angular.js:11706 Checking for files to upload
2015-11-16 15:55:59.111 angular.js:11706 idFile found, adding to uploadData
2015-11-16 15:55:59.111 angular.js:11706 Adding customerInfoPart to uploadData
2015-11-16 15:55:59.113 angular.js:11706 Upload data - {"idDocument":{"$ngfDataUrl":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAACegAAAGUCAYAAABEc1DzAAAMFmlDQ…EJSEACEpCABCQgAQlIQAISkIAEJCABCUhAAhKQgATWMYH/B2nQc4eYA6LeAAAAAElFTkSuQmCC"},"customerInfoPart":{"_ngfBlob":true}}
2015-11-16 15:55:59.118 angular.js:11706 Uploading data
2015-11-16 15:55:59.126 angular.js:11706 TypeError: Upload.upload(...).then(...).error is not a function
at Scope.SignupFileUpload.$scope.uploadFiles (signup-file-upload.controller.js:93)
at $parseFunctionCall (angular.js:12474)
at angular-touch.js:481
at Scope.$eval (angular.js:14570)
at Scope.$apply (angular.js:14669)
at HTMLButtonElement.<anonymous> (angular-touch.js:480)
at HTMLButtonElement.jQuery.event.dispatch (jquery.js:4435)
at HTMLButtonElement.elemData.handle (jquery.js:4121)(anonymous function) @ angular.js:11706(anonymous function) @ angular.js:8619Scope.$apply @ angular.js:14671(anonymous function) @ angular-touch.js:480jQuery.event.dispatch @ jquery.js:4435elemData.handle @ jquery.js:4121
2015-11-16 15:55:59.127 angular.js:11706 SESSSION INJECTOR Credentials 4904d093-11fd-4f5c-8d12-af9d837896bb
2015-11-16 15:55:59.393 angular.js:11706 Upload progress 64
2015-11-16 15:55:59.594 angular.js:11706 Upload progress 71
2015-11-16 15:55:59.695 angular.js:11706 Upload progress 78
2015-11-16 15:55:59.796 angular.js:11706 Upload progress 92
2015-11-16 15:55:59.896 angular.js:11706 Upload progress 99
2015-11-16 15:55:59.997 angular.js:11706 Upload progress 100
2015-11-16 15:55:59.998 angular.js:11706 Upload progress 100

As mentioned by danial in some case there was not a proper response from the server side. I am still not able to use .error or .success but i am at least able to process the success and error case in my existing controller logic.

Any improvements or suggestions on the controller are welcome.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM