4

I'm using jQuery File Uploader through Angular.js. I need to pass the server's response from the image upload to the Angular $scope, but I can't access the $scope within the done function:

   function LandmarkNewCtrl($location, $scope, db) {
      $('#fileupload').fileupload({
         url: '/api/upload',
         dataType: 'text',
         done: function (e, data) {

            $scope.landmark.avatar = data.result;

         }
      });
  }

Getting "Uncaught TypeError: Cannot read property 'landmark' of undefined" errors.

How do I pass $scope into the done: function() ?

3 Answers 3

5

You must not access HTML in angular controller. You should use a directive to do what you want :

angular.module('yourModule').directive('fileupload', function() {
  return function($scope, $element) {
    $element.fileupload({
      url: '/api/upload',
      dataType: 'text',
      done: function (e, data) {

        $scope.landmark.avatar = data.result;
        $scope.$apply();
      }
    });
  }
}); 

The done function is triggered by jQuery so you need to perform a $sope.$apply(), to force angular to refresh scope bindings.

Then use this directive in your template :

<div ng-app="yourModule">
    <div fileupload>Fileupload</div>
</div>

More information on wrapping a jQuery component : Beginner questions with AngularJS and directives - wrapping a jQuery component

Sign up to request clarification or add additional context in comments.

Comments

4

It's more recommended to do something like

angular.element('#fileupload').fileupload({
     url: '/api/upload',
     dataType: 'text',
     done: function (e, data) {

        $scope.landmark.avatar = data.result;

     }
  });

it should work

Comments

0

The $scope doesn't work inside a JQuery function although it was called using angular.element as suggested in keddour's answer.

Using a directive to invoke the function seems to be the valid answer.

For those who are looking for a simpler method to employ in special circumstances (such as in a dynamically loaded script), exchanging data via a global variable works too. This breaks some conventions - but Angular really is not perfect yet and sometimes we have to resort to odd methods to workaround problems.

Declare something like this in global scope.

angularBridge = {};

Now in your controller (I assumed it in a dynamic script):

demoApp.controlProvider.register('demoController', ['$scope', function($scope) {          

 angularBridge.$demoScope = $scope; 

 $scope.landmark.avatar = 0;      

}]);

Now you can use this in side an Angular controller or JQuery function to exchange data.

   function LandmarkNewCtrl($location, $scope, db) {
      $('#fileupload').fileupload({
         url: '/api/upload',
         dataType: 'text',
         done: function (e, data) {

            angularBridge.$demoScope.landmark.avatar = data.result;

         }
      });
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.