1

I am writing an angularjs app. The requirement is to display the user's data once the user logs in. So when an user successfully logs in, he/she is routed to the next view. My application is working fine upto this point. Now as the next view loads I need to display the existing records of the user. However at this point I see a blank page, I can clearly see in the console that the data is being returned but it is not binding. I have used $scope.$watch, $scope.$apply, even tried to call scope on the UI element but they all result in digest already in progress. What should I do? The page loads if I do a refresh

 (function () {
"use strict";

angular.module("app-newslist")
    .controller("newsController", newsController);

function newsController($http,$q,newsService,$scope,$timeout)
{

    var vm = this;
    $scope.$watch(vm);
    vm.news = [];
    vm.GetTopNews = function () {
        console.log("Inside GetTopNews");
        newsService.GetNewsList().
        then(function (response)
        {
            angular.copy(response.data, vm.news);
        }, function () {
            alert("COULD NOT RETRIEVE NEWS LIST");
        });
    };
    var el = angular.element($('#HidNews'));
    //el.$scope().$apply();
    //el.scope().$apply();
    var scpe = el.scope();
    scpe.$apply(vm.GetTopNews());
    //scpe.$apply();
}

})();

Thanks for reading

1
  • 1
    How are you displaying vm.news in the UI? Commented Apr 29, 2016 at 20:15

1 Answer 1

1

you don't show how you're binding this in your template.. I tried to recreate to give you a good idea.

I think the problem is the way you're handling your promise from your newsService. Try looking at $q Promises. vm.news is being updated by a function outside of angular. use $scope.$apply to force refresh.

the original fiddle is here and a working example here

(function() {
  "use strict";

  var app = angular.module("app-newslist", [])
    .controller("newsController", newsController)
    .service("newsService", newsService);

  newsController.$inject = ['$http', 'newsService', '$scope']
  newsService.$inject = ['$timeout']

  angular.bootstrap(document, [app.name]);

  function newsController($http, newsService, $scope) {

    var vm = this;
    vm.news = $scope.news = [];
    vm.service = newsService;

    console.warn(newsService)

    vm.message = "Angular is Working!";

    vm.GetTopNews = function() {
      console.log("Inside GetTopNews");

      newsService.GetNewsList().
      then(function(response) {
        $scope.$apply(function() {
          $scope.news.length > 0 ? $scope.news.length = 0 : null;
          response.data.forEach(function(n) {
            $scope.news.push(n)
          });

          console.log("VM", vm);
        })

      }, function() {
        alert("COULD NOT RETRIEVE NEWS LIST");
      });
    };

  }

  function newsService($timeout) {
    return {
      GetNewsList: function() {
        return new Promise(function(res, rej) {
          $timeout(function() {
            console.log("Waited 2 seconds: Returning");
            res({
              data: ["This should do the trick!"]
            });
          }, 2000);
        })
      }
    }
  }

})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.9/angular.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.min.js"></script>


<body>


  <div class="main">
    <div class="body" ng-controller="newsController as vm">
      Testing: {{ vm.message }}
      <br>{{ vm.news }}
      <br>{{ vm }}
      <br>
      <button class="getTopNewsBtn" ng-click="vm.GetTopNews()">Get News</button>
      <br>
      <ul class="getTopNews">
        <li class="news-item" ng-repeat="news in vm.news track by $index">
          {{ news | json }}
        </li>
      </ul>
    </div>
  </div>

</body>

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

2 Comments

I can easily bind with button click but I want the binding on page load. I can see data being fetched in the console log. I doubt the data is fetched after the UI is loaded and angular digest has completed. Once I refresh the page the binding works. View <table class="table table-responsive table-striped"> <tr ng-repeat="info in vm.news"> <td>{{info.title}}</td> <td>{{info.highlights}}</td> </tr> </table>
instead of binding to an ng-click, just call the function in your controller. function newsController($http, newsService, $scope) { /* Previous Code */ GetTopNews();} .. this will do the same as pressing btn and when refreshing page, will always load results first thing.

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.