Search code examples
javascriptangularjsng-file-upload

Angular wont update view even after $apply was used


I am including an html file using inside my main page using

<div ng-controller="detailViewCtrl"  ng-include="'partials/template.html'"></div>

inside this script there is a list showing some documents.

<li ng-repeat="document in relatedDocuments" style="cursor: pointer;" class="box" ng-click="gotoDocument(document)">
  <div><i class="fa fa-file-pdf-o"></i> <span>{{document.name | limitTo: 20 }}{{document.name.length > 20 ? '...' : ''}}</span></div>
  <md-tooltip md-direction="top">
    {{document.name}}
  </md-tooltip>
  <thumbnail file-type="{{document.filetype}}" source="document.fullpath" max-height="150" max-width="210"></thumbnail>
</li>

At some point using a button that is inside another template, is included in pretty much the same way, I might upload a new pdf file. The file is uploaded to my server and a query is made requesting the documents list (that is now expected to contain this new document). This query is in the same function that is initially called to fill relatedDocuments. This time though the list does not update, no matter how many documents I upload. Only if I refresh I will see the newly uploaded files.

Trying to force a $digest myself will not have any effect, and my view will remain unchanged even though I can see the printed list in my console after the promise is resolved.

The controller looks like this:

.controller('detailViewCtrl', function($scope, $i18next, $routeParams,...    

$scope.relatedDocuments = [];

$scope.getRelatedDocuments = function(document) {
  myAPI.getRelatedDocuments($scope.id).then(function(response) {
    $scope.relatedDocuments = response.data.result;    
    console.log("getRelatedDocuments", $scope.relatedDocuments);
  });
};

$scope.getRelatedDocuments();

Also inside this module there is an uploadDocument() function that after it uploads a document it calls getRelatedDocuments(). This function uses ng-file-upload to deal with the actual data transfer to the server.

$scope.uploadFile = function(file) {
    file.upload = Upload.upload({
      url: tempPath,
      method: 'POST',
      file: file,
      sendFieldsAs: 'form',
      fields: {
        docid: $scope.id
      }
    });

    file.upload.then(function(response) {
      $timeout(function() {
        file.result = response.data;
      });
    }, function(response) {
      $scope.getRelatedDocuments(); // Here I try to update the list
      if (response.status > 0)
        $scope.errorMsg = response.status + ': ' + response.data;
    }, function(evt) {
      file.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
    });
  }

This upload function is called after the corresponding button is pressed somewhere in the main page. Since I can see the log message, and the response I assumed that everything goes as should.

A plunk that contains the relevant parts of the code can be found here. It does not work of curse since it needs the backend to save and get the documents list, but it's a good reference still.

Does anyone know why is this happening?


Solution

  • It seems that I should not had used the ng-controller directive when including the two templates since they are called from a page that also uses the same controller. If you have the same controller nested onto itself then Angular may behave on unexpected ways.