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.
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.
Related
i want to invoke angularjs function (DeptSpecific) on page load and am passing ID as the parameter which is hard coded. And that i am passing via ng-init="DeptSpecific('1')". I am learning angularjs please suggest me how to call a function and pass a parameter to it on page load without any click or anything just when a page load a function should be called. If you are thinking why i used ng-init ..there is no specific reason for this it might be wrong but it calls the function well i can see that in debugger (f12) but $scope.s i undefined even though there is a matched ID.
$scope.DeptSpecific = function (ID) {
var BelongsToThisDepartment = [];
$http.get('/Department/getDept').success(function (response) {
$scope.departments = $scope.$eval(response);
});
angular.forEach($scope.departments, function (item1) {
if (item1.ID == ID) {
BelongsToThisDepartment.push(item1);
}
})
$scope.s = $scope.$eval(angular.toJson(BelongsToThisDepartment));
// console.log(JSON.stringify($scope.s));
}
<div ng-app="MyApp">
<div ng-controller="MyController">
<table class="tableData" border="0" cellspacing="0" cellpadding="0" ng-init="DeptSpecific('1')">
<thead>
<tr>
<th></th>
<th>ID</th>
<th>NAME</th>
<th>LOCATION</th>
</tr>
</thead>
<tbody ng-repeat="O in s">
<tr ng-class-even="'even'" ng-class-odd="'odd'">
<td class="CX" ng-click="student(O.ID)"><span>+</span></td>
<td>{{O.ID}}</td>
<td>{{O.Name}}</td>
<td>{{O.Location}}</td>
</tr>
Looking at your code, using ng-init is fine, but your $scope.departments may not be accessible outside of the .success method.
angular.module('MyApp')
.controller('MyController', ['$scope', function($scope) {
$scope.DeptSpecific = function (ID) {
var BelongsToThisDepartment = [];
$http.get('/Department/getDept')
.success(function (response) {
$scope.departments = $scope.$eval(response);
angular.forEach($scope.departments, function (item1) {
if (item1.ID == ID) {
BelongsToThisDepartment.push(item1);
}
})
$scope.s = $scope.$eval(angular.toJson(BelongsToThisDepartment));
console.log($scope.s);
});
}
}]);
now if that works for you but you also want to be able to access $scope.s outside of that .success;
You can write a function, add it into .success pass the value returned onSucess, and do what you want to do.
.success(function(response) {
callAFunction(response);
}
I'm setting up an Angular JS app to consume a Django REST API, and I'm stuck on the rendering of data.
I already asked another question (this), but the solution that I've been given doesn't work.
I was wondering that maybe there is something wrong in the API view, could it be a problem when trying to render the data from the Angular controller?
Anyway, this is my Angular app + template (edited as suggested in the other stackoverflow question)
base.html
<body ng-app="schoolApp" 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>
app.js
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) {
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));
});
});
I was thinking that maybe there is some problem on the view, so here's the REST API view
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
What am I doing wrong?
UPDATE:
This is what I get
Data on the console: yes.
Data on the tables: no.
As you are using controllerAs syntax, you have binded all data to controller context. So you could get data on view using its alias like vm.classrooms
<tr ng-repeat="classroom in vm.classrooms">
Have you tried to output in the html the content of the variable vm.classrooms.
You can do it with <pre>{{vm.classrooms|json}}</pre>
It seems to me that you are not binding correctly the variables inside the table,
i can't see it clearly in the picture, it can be {{ classroom.school.academic_year }} ??
I am pretty new to angular and I am working on a data entry web page. The web page has three tabs. Vendor, Products and Types. I started working on the Types tab first. I'd be happy if I could just display the results of a GET request to my Rest API. My Rest API works:
# curl http://192.168.1.115:8080/type
[
{"_id":"56415e7703aba26400fcdb67","type":"Skiing","__v":0},
{"_id":"56417a8503aba26400fcdb68","type":"Bannana","__v":0},
{"_id":"56417a8d03aba26400fcdb69","type":"Carrot","__v":0},
{"_id":"56417a9603aba26400fcdb6a","type":"Beer","__v":0}
]
Here's the pertinent part of my html UPDATED I now have st-safe-src=all_typesbut still no joy ...
<div ng-controller="typeCtrl" class="tab-pane" id="types-v">
<p>The number {{3 + 4}}.</p>
<p>message is {{message}}</p>
<table st-table="displayedCollection" st-safe-src="all_types" class="table table-striped">
<tbody>
<tr ng-repeat="x in displayedCollection">
<td>{{x.type}}</td>
</tr>
</tbody>
</table>
</div> <!-- end Types Tab -->
... and here is my typeCtrl.js ...
app.controller("typeCtrl", function($scope,$http) {
$scope.type_to_look_for = "";
$scope.message = "this is the message. (from typeCtrl)";
$scope.itemsByPage=15;
$scope.all_types = function () {
$http.get("http://192.168.1.115:8080/type").then(function(response) {
console.log(response);
console.log(response.data);
return response.data;
});
}
});
... but when I click on the Types tab my data does not display. I looked developer console and I do not even see the GET request kickoff. And my web page looks like this ...
... what am I doing wrong?
There is nothing that calls all_types. Run http.get and assign the response to all_types
app.controller("typeCtrl", function($scope,$http) {
$scope.type_to_look_for = "";
$scope.message = "this is the message. (from typeCtrl)";
$scope.itemsByPage=15;
$http.get("http://192.168.1.115:8080/type").then(function(response) {
$scope.all_types = response;
});
}
});
My understanding is that you want a get request to be fired whenever you click on the Types tab, right? If so, just use ng-click to call your all_types function as follows:
<div ng-controller="typeCtrl" ng-click="all_types()" class="tab-pane" id="types-v" >
Also, you do not need to return response.data in your controller. Just assign the data to a scope object and use it in the template.
And finally, I would suggest wrapping all your ajax calls in factories and then inject those factories in your controllers.
Here is your code
<div ng-controller="typeCtrl" class="tab-pane" id="types-v">
<p>The number {{3 + 4}}.</p>
<p>message is {{message}}</p>
<table st-table="types" class="table table-striped"><!-- Do not need st-safe-src -->
<tbody>
<tr ng-repeat="x in types"><!-- Use the Collection name as types-->
<td>{{x.type}}</td>
</tr>
</tbody>
</table>
</div>
Controller Code
app.controller('typeCtrl', function($scope, $http) {
$scope.type_to_look_for = "";
$scope.message = "this is the message. (from typeCtrl)";
$scope.itemsByPage=15;
$http.get("http://192.168.1.115:8080/type").then(function(response) {
console.log(response.data);
$scope.types = response.data;
});
});
Here is working the plunker
I am new to angular JS. I have created a simple page using ngRoute.
In the first view I have a table, and on clicking it redirects to second view.
But I have called two functions using ng-click the changeView functions is running fine. But the second function fails to execute on the second view.
But Its running fine if using on the first view itself.
Heres the code for first view
Angular.php
<div ng-app="myApp" ng-controller="dataCtr">
<table class='table table-striped'>
<thead>
<tr>
<td>Title</td>
<td>Stream</td>
<td>Price</td>
</tr>
</thead>
<tbody>
<tr ng-repeat = "x in names | filter:filtr | filter:search" ng-click=" disp(x.id);changeView()">
<td >{{ x.Title }}</td>
<td>{{ x.Stream }}</td>
<td>{{ x.Price }}</td>
</tr>
</tbody>
</table>
</div>
heres the second View
details.php:
<div ng-app="myApp" ng-controller="dataCtr">
<div class="container">
SELECTED:<input type="textfield" ng-model="stxt">
</div>
</div>
heres the js file:
var app = angular.module("myApp", ['ngRoute']);
app.config(function($routeProvider) {
$routeProvider
.when('/angular', {
templateUrl: 'angular.php',
controller: 'dataCtr'
})
.when('/details', {
templateUrl: 'details.php',
controller: 'dataCtr'
})
.otherwise({
redirectTo: '/angular'
});
});
app.controller('dataCtr', function($scope ,$http ,$location ,$route ,$routeParams) {
$http({
method: "GET",
url: "json.php"})
.success(function (response) {$scope.names = response;});
$scope.changeView = function()
{
$location.url('/details');
};
$scope.disp = function(id)
{
$scope.stxt = $scope.names[id-1].Title;
};
});
The disp function is working fine on the angular view. But not being routed on the second view. I think the syntax for calling the two views in ng click is correct. OR if there any other method to call the associated table cell value to the second view. Please Help.
After a lots of research i figured it out.I used a factory service
app.factory('Scopes', function ($rootScope) {
var mem = {};
return {
store: function (key, value) {
$rootScope.$emit('scope.stored', key);
mem[key] = value;
},
get: function (key) {
return mem[key];
}
};
});
Added this to JS.
Because The scope gets lost on second Controller ,Services help us retain the scope value and use them in different controllers.Stored the scope from first controller
app.controller('dataCtr', function($scope ,$http ,$location,$rootScope,Scopes) {
Scopes.store('dataCtr', $scope);
//code
});
and loaded in the seconded controller.
app.controller('dataCtr2', function($scope ,$timeout,$rootScope,Scopes){
$scope.stxt = Scopes.get('dataCtr').disp;
});
Second view is not working because you cannot use $scope.$apply() method.
$apply() is used to execute an expression in angular from outside of the angular framework.$scope.$apply() right after you have changed the location Angular know that things have changed.
change following code part ,try again
$location.path('/detail');
$scope.$apply();
I am using angular JS with ng-tables with rails as an API.
i successfully integrated ng-tables with server side pagination. The issue i am facing is whenever i go back list page from detail page. table data is not visible. i checked in logs and using breakpoints . i can see data but not lucky.
my controller is sampleController.js
function sampleController($scope, $http, ngTableParams, $state, Auth) {
$data = [];
$scope.tableParams = new ngTableParams({
page: 1,
count: 10
}, {
getData: function($defer, params) {
$http.get('sample.json', {
params: {
page: params.page()
}
})
.success(function(response, status) {
$data = response.data;
params.total(response.count);
$defer.resolve($data);
});
}
});
and my html template is as follows
<table ng-table="tableParams" class="table ng-table-responsive">
<tr ng-repeat="data in $data.tasks">
<td data-title="'Title'">
{{data.title}}
</td>
</tr>
</table>
also i referred issue . but i couldn't able to fix it.
I appreciate your time and input. Hoping for solution from you guys.