I'm currently working on some code in Angular which loads a list of blogposts to a website. I have a module and controller, and have an ng-repeat loop set up to iterate through a json which acts as an index for a bunch of html files. However, the tags which should be outputting data from my index object are all empty on the final page.

app.js:

var PersonalApp = angular.module('PersonalApp', [
  'ngRoute',
  'MasterCtrl'
]);

PersonalApp.config(['$routeProvider',
  function($routeProvider) {
    $routeProvider.
      when('/blog', {
        templateUrl: 'partials/blog.html',
        MasterCtrl: 'MasterCtrl'

      }).
      when('/about', {
        templateUrl: 'partials/about.html',
        MasterCtrl: 'MasterCtrl'

      }).
      when('/projects', {
        templateUrl: 'partials/about.html',
        MasterCtrl: 'MasterCtrl'

      }).
      when('/contact', {
        templateUrl: 'partials/about.html',
        MasterCtrl: 'MasterCtrl'

      }).
      otherwise({
        redirectTo: '/blog'
      });
  }]);

MasterCtrl.js:

var MasterCtrl = angular.module('MasterCtrl', []);

MasterCtrl.controller('MasterCtrl', ['$scope', '$http',
    function ($scope) {
        $.ajax({
            url: '../BlogPosts/posts.json',
            dataType: 'json',
            success: function (bposts) {
                $scope.bposts = (bposts);
                bposts = JSON.stringify(bposts)
                console.log(bposts);
            }
        });
    }]);

blog.html:

<article ng-repeat="posts in bposts" class="post-173 post type-post status-publish format-standard has-post-thumbnail hentry category-uncategorized masonry-brick" style="position: absolute; left: 0px; top: 0px;">
                <div class="item-sizer">

                    <header class="entry-header blog-entry-header">

                        <div class="entry-data">
                            <span class="posted-on">
                                <a ng-href="/../BlogPosts/{{posts.ID}}" rel="bookmark">
                                    <time class="entry-date published updated" datetime="2015-08-20T02:48:02+00:00">{{posts.ID}}</time>
                                </a>
                            </span>

                        </div>
                        <h1 class="entry-title"><a ng-href="/../BlogPosts/{{posts.ID}}" rel="bookmark">{{posts.Title}}</a></h1> </header><!-- .entry-header -->
                        {[posts.ID}}

                    <div class="entry-content">
                        <p>{{posts.Summary}}<a class="read-more" ng-href="/../BlogPosts/{{posts.ID}}">Continue reading</a></p>
                    </div><!-- .entry-content -->
                </div>
            </article>

Here is the console output of my originally jQuery:

{"posts":[{
    "ID":"441770384",
    "Title":"TestPost",
    "Summary":"Doot Doot",
    "Thumb":"null"
},{
    "ID":"1441835958",
    "Title":null,
    "Summary":"null",
    "Thumb":"‌​null"
},{
    "ID":"1441836000",
    "Title":null,
    "Summary":"null",
    "Thumb":"null"
},{
    "ID":"14‌​41836039",
    "Title":"dfasdf",
    "Summary":"null",
    "Thumb":"null"
}]}
share|improve this question
1  
use $http instead of $.ajax so you don't have to use $apply() for each request. Angular doesn't know about $.ajax so you have to tell it to run digests when you change scope. – charlietfl Sep 22 '15 at 3:56
    
Congrats on separating your app into modules, it's a rare site on StackOverflow. You'll find it much easier to work with – Phil Sep 22 '15 at 4:02
up vote 1 down vote accepted

You seem to be using jQuery's .ajax method instead of $http. Using jQuery won't trigger a digest cycle and as such, your scope changes won't be reflected in your templates. Use $http instead...

Simply change your "MasterCtrl" controller to

.controller('MasterCtrl', ['$scope', '$http',
    function ($scope, $http) {
        $http.get('../BlogPosts/posts.json').then(function(response) {
            $scope.bposts = response.data.posts;
        });
    }]);

and try to avoid using jQuery in Angular apps.

See $apply() for more information about the digest cycle and what you should do if you insist on using third party libraries like jQuery.

share|improve this answer
    
I had this originally, but it wasn't working either. Just tried your code and it didn't work. – Adrian Smith Sep 22 '15 at 4:06
    
@AdrianSmith "didn't work" isn't a very good problem description. What does the data in posts.json look like? – Phil Sep 22 '15 at 4:07
    
Using your version of the code had no change on what the actual page looks like. Here is the console output of my originally jQuery: {"posts":[{"ID":"441770384","Title":"TestPost","Summary":"Do‌​ot Doot","Thumb":"null"},{"ID":"1441835958","Title":null,"Summa‌​ry":"null","Thumb":"‌​null"},{"ID":"144183‌​6000","Title":null,"‌​Summary":"null","Thu‌​mb":"null"},{"ID":"1‌​441836039","Title":"‌​dfasdf","Summary":"n‌​ull","Thumb":"null"}‌​]} – Adrian Smith Sep 22 '15 at 4:14
    
Console output is also identical after using your code. – Adrian Smith Sep 22 '15 at 4:16
2  
@Romulo $scope.$apply() will throw an error in my answer. It is totally unnecessary here – Phil Sep 22 '15 at 4:18

Since you are retrieving your data using JQuery ($.ajax), you have to invoke the $scope.$apply() so AngularJS can create the binding and update your view.

You can check When to use $scope.$apply() for more info.

share|improve this answer
    
Where would I use that? – Adrian Smith Sep 22 '15 at 4:09
    
You should use that after you assign the retrieved data to your scope variable. In your case that would be after $scope.bposts = (bposts); – Romulo Sep 22 '15 at 4:13
    
I switched to the non-jQuery version of the code as suggested by @Phil, but the same issue is still occurring. – Adrian Smith Sep 22 '15 at 4:20
    
OP shouldn't be using $.ajax at all, especially since they're even injecting the $http service. – Phil Sep 22 '15 at 4:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.