javascriptangularjsfirebaseangularjs-apply

How to Pass data from Third-Party Library Callback (firebase) to View in AngularJS


I'm working on upload files using angularjs and firebase I'm trying pass parameters from controller to view inside state_changed event It's not working , I can print it on controller but can't use it into view

these code that I used

// File or Blob named mountains.jpg
var file = "";

// Create the file metadata
var metadata = {
  contentType: 'image/jpeg'
};

// Upload file and metadata to the object 'images/mountains.jpg'
var uploadTask = storageRef.child('images/' + file.name).put(file, metadata);

// Listen for state changes, errors, and completion of the upload.
uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED, // or 'state_changed'
  function(snapshot) {
    // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
    var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
    console.log('Upload is ' + progress + '% done');
    $scope.progress = progress;
    switch (snapshot.state) {
      case firebase.storage.TaskState.PAUSED: // or 'paused'
        console.log('Upload is paused');
        break;
      case firebase.storage.TaskState.RUNNING: // or 'running'
        console.log('Upload is running');
        break;
    }
  }, function(error) {
  switch (error.code) {
    case 'storage/unauthorized':
      // User doesn't have permission to access the object
      break;

    case 'storage/canceled':
      // User canceled the upload
      break;

    ...

    case 'storage/unknown':
      // Unknown error occurred, inspect error.serverResponse
      break;
  }
}, function() {
  // Upload completed successfully, now we can get the download URL
  var downloadURL = uploadTask.snapshot.downloadURL;
});
<pre>{{progress}}</pre>


Solution

  • Because the firebase event happens outside the AngularJS framework, changes to $scope need to use $scope.$apply()

    $scope.$apply(function() {
        $scope.progress = progress;
    });
    

    From the Docs:

    Angular modifies the normal JavaScript flow by providing its own event processing loop. This splits the JavaScript into classical and Angular execution context. Only operations which are applied in Angular execution context will benefit from Angular data-binding, exception handling, property watching, etc... You use $apply() to enter Angular execution context from JavaScript.

    Keep in mind that in most places (controllers, services) $apply has already been called for you by the directive which is handling the event. An explicit call to $apply is needed only when implementing custom event callbacks, or when working with third-party library callbacks.

    For more information, see