1

I'm setting up an Angular JS app that consumes a Django REST API.
I want to show a HTML list of classrooms.
This is my template

<body>
    <div ng-app="schoolApp" ng-controller="schoolCtrl">
        <table class="table table-striped">
            <thead>
                <tr>
                    <th>Classroom</th>
                    <th>School</th>
                    <th>Floor</th>
                    <th>Academic year</th>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="classroom in classrooms">
                    <td>{{classroom.classroom}}</td>
                    <td>{{classroom.school.school_name}}</td>
                    <td>{{classroom.floor}}</td>
                    <td>{{classroom.academic_year}}</td>
                </tr>
            </tbody>
        </table>
    </div>
</body>

This is the script

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

schoolApp.factory('Classroom', ['$resource', function($resource) {
    return $resource('/classrooms/?format=json', {}, {
        query: {
            method: 'GET',
            isArray: true,
        }
    });
}]);

schoolApp.controller('schoolCtrl', function($scope, Classroom) {
        Classroom.query().$promise.then(function(data) {
        var data = Classroom.query({});
        $scope.classrooms = data;
        console.log(Classroom.query({}));
    });
 });

The problem is, I think, that I get - I can see it in the console -, $resolved: false.
How can I resolve that?
UPDATE:

Given that I can't resolve the issue, I was wondering that maybe I've set up badly something else, like... the view?
This is the one I got

class HomePageView(TemplateView):
    template_name = 'school_app/base.html'

class StudentViewSet(viewsets.ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer


class ClassroomViewSet(viewsets.ModelViewSet):
    queryset = Classroom.objects.all()
    serializer_class = ClassroomSerializer

Maybe I have to add something to HomePageView or setting it up in another way?

UPDATE:

This is what I get on the console with the debugger "on"

Success: [{"school":{"id":1,"school_name":"IPSIA F. Lampertico","address":"Viale Giangiorgio Trissino, 30","city":"Vicenza"},"academic_year":"2015/2016","classroom":"1^A","floor":0,"students":[{"classroom":1,"first_name":"Stefano","last_name":"Rossi","gender":"M","birthday":"1998-06-22"},{"classroom":1,"first_name":"Luca","last_name":"Possanzini","gender":"M","birthday":"1999-11-22"}]},{"school":{"id":2,"school_name":"ITIS A. Rossi","address":"Via Legione Gallieno, 52","city":"Vicenza"},"academic_year":"2015/2016","classroom":"2^B","floor":0,"students":[{"classroom":2,"first_name":"Sergio","last_name":"Lazzari","gender":"M","birthday":"2001-01-29"}]},{"school":{"id":3,"school_name":"Liceo Scientifico G.B. Quadri","address":"Viale Giosuè Carducci, 17","city":"Vicenza"},"academic_year":"2015/2016","classroom":"3^C","floor":0,"students":[{"classroom":3,"first_name":"Lucia","last_name":"Modella","gender":"F","birthday":"2000-05-22"}]},{"school":{"id":4,"school_name":"Istituto Professionale Statale B.Montagna","address":"Via Mora, 93","city":"Vicenza"},"academic_year":"2015/2016","classroom":"4^D","floor":1,"students":[{"classroom":4,"first_name":"Mirko","last_name":"Van Der Sella","gender":"M","birthday":"2002-12-25"}]}]

Practically, the whole Json response.

1
  • $resolved should automatically be set to true by Angular provided that your REST API request succeeds. Check your API call works by hitting it directly with another client. Also, you shouldn't need to make further queries inside then(), the $scope.classrooms = data; statement should be sufficient. Commented Jun 27, 2016 at 0:00

1 Answer 1

1

When you call query of $resource, it returns a reference to an object or array with $resolved = false, until the REST API calls finishes and populates your object. So, $resolved = false is probably correct and indicates that you have not receive the data yet.

Here is a working plunker based on your code.

The controller is:

app.controller('schoolCtrl', function($scope, Classroom) {
  var vm = this;
  vm.name = 'World';
   Classroom.query().$promise.then(function(data) {
     console.log('Success: '+JSON.stringify(data));
     vm.classrooms = data;

   }, function (reason) {
     console.log('ERROR: '+JSON.stringify(reason));
   });
});

This is what I do for debugging REST web API... once the call works, you can switch to a lighter version:

app.controller('schoolCtrl', function($scope, Classroom) {
  var vm = this;
  vm.name = 'World';
  vm.classrooms = Classroom.query();
});

I created a classroom JSON (guessing your format):

[
    {"classroom":"0", "school": {"school_name":"anc"} },
        {"classroom":"1", "school": {"school_name":"Sorbonee"} }

    ]

And the HTML:

<body ng-controller="schoolCtrl as vm">
    <p>Hello {{vm.name}}!</p>
    <div>
        <table class="table table-striped">
            <thead>
                <tr>
                    <th>Classroom</th>
                    <th>School</th>
                    <th>Floor</th>
                    <th>Academic year</th>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="classroom in vm.classrooms">
                    <td>{{classroom.classroom}}</td>
                    <td>{{classroom.school.school_name}}</td>
                    <td>{{classroom.floor}}</td>
                    <td>{{classroom.academic_year}}</td>
                </tr>
            </tbody>
        </table>
    </div>
  </body>

I changed the URL in the factory to make it work on plnkr, but the rest is identical:

app.factory('Classroom', ['$resource', function($resource) {
    return $resource('classrooms?format=json', {}, {
        query: {
            method: 'GET',
            isArray: true,
        }
    });
}]);

Please note that I use var vm=this and ControllerAs syntax to avoid any scope issues based on this article.

On ngResource from the doc: "It is important to realize that invoking a $resource object method immediately returns an empty reference (object or array depending on isArray). Once the data is returned from the server the existing reference is populated with the actual data. This is a useful trick since usually the resource is assigned to a model which is then rendered by the view. Having an empty object results in no rendering, once the data arrives from the server then the object is populated with the data and the view automatically re-renders itself showing the new data. This means that in most cases one never has to write a callback function for the action methods."

Let us know if this helps.

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

3 Comments

Thank you for the solution, but it's not working anyway. With the debugged called on the controller, I get all the data in the console - as I did before -, but the template is not rendering the data. Could it be something I missed on the view? I'm updating the question, if you can take a look again.
Could you share what you see in the console? That would help with spotting a problem with the view. Thanks
Updated the question.

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.