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

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

0
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;

         }
      });
  }

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.