ng-table data not showing on page load - angularjs

I have integrated ngTable into my mean.io stack and I'm having trouble with populating the table on page load. If I select one of the column headers, the data shows up and the table works as advertised.
Here is my html
<table ng-table="tableParams" class="table">
<tbody ng-repeat="p in $data">
<tr id="tr{{p._id}}" ng-class-odd="'odd'" ng-class-even="'even'">
<td class="rowTd" data-title="'Task Code'" sortable="'task_code'">{{p.task_code}}</td>
<td class="rowTd" data-title="'Task Name'" sortable="'task_name'">{{p.task_name}}</td>
<td class="rowTd" ><input type=button id="editRowBtn{{p._id}}" value="edit"
ng-click="setEditId(p._id)"></td>
</tr>
<tr ng-show="editId===p._id" ng-if="editId===p._id">
<td colspan="7" ng-include src="'editRow.html'"></td>
</tr>
</tbody>
</table>
Here is my controller code.
var data = GeneralTasks.query();
$scope.tableParams = new ngTableParams({
page: 1,
count: 10
},{
total: data.length,
getData: function($defer, params) {
params.total(data.length);
$defer.resolve(data.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
$scope.editId = -1;
$scope.setEditId = function(pid) {
$scope.editId = pid;
};
I am new to using this table so i'm sure there is something i'm overlooking.

Wanted to provide the answer to my question so it may help others. Anytime an item in the table is added or removed, the table must be reloaded. Since $save and $remove invoke a callback function, just inserted the following for updating the table.
$scope.add = function() {
if (!$scope.tasks) $scope.tasks = [];
var task = new GeneralTasks({
task_code: $scope.task_code,
trade: $scope.trade,
task: $scope.task,
task_name: $scope.task_name
});
task.$save(function(response) {
$scope.tasks.push(response);
var data = $scope.tasks;
$scope.tableParams.total(data.length);
$scope.tableParams.reload();
});
this.task_code = this.trade = this.task = this.task_name = '';
};
First i update the $scope list with the response and then update the tables data and length. Then just call reload.
As I've stated earlier, i do this for $save and $remove. Here is the $remove code.
$scope.remove = function(task) {
for (var i in $scope.tasks) {
if ($scope.tasks[i] === task) {
$scope.tasks.splice(i, 1);
}
}
task.$remove();
var data = $scope.tasks;
$scope.tableParams.total(data.length);
$scope.tableParams.reload();
};
I have noticed that when I edit a name in the list and then cancel, the name does not reset. I suppose I should add similar code for the cancel action but I'm lazy and that's the least of my worries for now. :)
Hope this helps someone else.

Related

$resolved: false in Angular JS response

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.

Filtering AngularJS Table Based Off Value In Separate Controller

Ok so I am very new to Angular, only been playing with it for three days now. I am running into an issue when trying to filter a table I created based on the value of a "select option" in another controller. Basically I have one controller that performs a REST call to populate a "select" menu dynamically. Then I have another controller that makes a separate REST call to populate a table. What I am trying to do is filter the table based off the "value" from the "selected" option. For example if I choose the "option" with a value of "2", the table would filter to only show results with an "ID" of "2". I may be going about this in a completely wrong way but from what I am reading I need to create a "service" to store the "value" of the "option" so that I can reference it in the controller that populates the table. If anyone could provide some incite on how to go about doing this I would greatly appreciate it. Please see my code bellow...
Angular Code
angular.module('restCalls',[])
// Controller for Project REST Call
.controller('displayProj',function($scope, $http) {
$http({type: "GET", url:"http://my_api_call/", headers: { "ACCEPT": "application/json;odata=verbose"}})
.success(function(data) {
$scope.results = data.d.results;
$scope.projects = [];
for(i=0; i < data.d.results.length; i++) {
$scope.projects.push({name: data.d.results[i].Title , id: data.d.results[i].Id});
};
$scope.getSelectedOption = function(value) {
console.log($scope.selectedProject.id);
};
});
})
// Controller for ChargeCode REST Call
.controller('displayCC',function($scope, $http) {
$http({type: "GET", url:"http://my_api_call/", headers: { "ACCEPT": "application/json;odata=verbose"}})
.success(function(data) {
$scope.results = data.d.results;
$scope.projects = [];
for(i=0; i < data.d.results.length; i++) {
$scope.projects.push({id: data.d.results[i].Master_x0020_ID, cc: data.d.results[i].Title, name: data.d.results[i].deltek_x0020_name});
}
})
});
HTML Code
<div data-ng-app="restCalls" class="ng-scope">
<div id="project_menu_select" data-ng-controller="displayProj" class="ng-scope">
<p class="ng-binding">ID of selected project is:​​​​ {{selecteProject.id}} </p>
<select data-ng-model="selectedProject" data-ng-options="project.name for project in projects" class="ng-pristine ng-valid ng-empty form-control ng-touched ng-untouched" data-ng-change="getSelectedOption()">
</select>​ </div>
<div id="charge_codes_table" data-ng-controller="displayCC" class="ng-scope">
<table class="table table-striped">
<thead>
<tr>
<th>Project ID</th>
<th>Charge Code</th>
<th>Deltek Name</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="project in projects">
<td data-ng-if="project.id == (option value)">{{project.id}}</td>
<td data-ng-if="project.id == (option value)">{{project.cc}}</td>
<td data-ng-if="project.id == (option value)">{{project.name}}</td>
</tr>
</tbody>
</table>
</div>
</div>
Anyway you have both table and select option in one page. Better to use single controller for both.
You can also use common parent controller for both of these controllers.
OR
You can use $rootScope to share the variables. Set as $rootScope.selectedValue = 2 from one controller and then you can access this as $rootScope.selectedValue from another controller.
OR
You can use services to share the functions and variables as follows,
app.service("shared", function () {
var selectedOption = {};
return {
getSelectedOption: function () {
return selectedOption;
},
setSelectedOption: function (value) {
selectedOption = value;
}
};
});

Angularjs data is not updated on call of $apply

I have a controller that reads data via rest and displays it in a table - this part is working fine. Additionally i added a WebSocket and want to update the table if Websocket receives data. Here is the Code:
app.controller('allBookingsCtrl', function($scope, $http, currentUser){
$scope.bookingsList = [];
var ws = new WebSocket(wsRootUrl + '/allbookings');
ws.onmessage = function(message){
$scope.$apply(function(){
$scope.bookingsList = message.data;
alert(message.data);//displays correct data!
});
};
$http.get(rootUrl + '/timetracker/booking/all').success(function(response) {
$scope.bookingsList = response;
});
});
The problem is the table is not updated on call of apply. I debugged and could trigger onmessage by changing data from another browser. the content of data is also correct, no error is thrown.
So how to update the table/scope with data received by websocket?
here is html:
<table ng-controller="allBookingsCtrl" class="table">
<thead>
<tr>
<th>#</th>
<th>user</th>
<th>project</th>
<th>start</th>
<th>end</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="booking in bookingsList">
<td>{{$index + 1}}</td>
<td>{{booking.usersProjects.user.name}}</td>
<td>{{booking.usersProjects.project.name}}</td>
<td>{{booking.start | date:'yyyy-MM-dd HH:mm:ss' }}</td>
<td>{{booking.end | date:'yyyy-MM-dd HH:mm:ss' }}</td>
</tr>
</tbody>
</table>
Small Edit:
if i add alert(data); at the end of on message i see the alert with correct data! So only the apply with the list isn't working correctly.
added plunkr
I tried to reproduce this in plunkr and with no websocket - tried to get the update on ng-click. But this isn't working neither - here the click is not doing anything.
Can you change this line
$scope.bookingsList = data;
to
$scope.bookingsList = message.data;

How to dynamically re-draw data in table. Angular ngTable

I have controller with just 1 function getList(). When I call it first time - everything is just fine and my table show proper data. But when I call this function again (with new params in order to get different data in response), I still have data in table from the first call. How to reload/redraw/refresh data?
module.controller("IPsCtrl", function($scope, $filter, IPService, ngTableParams) {
$scope.data_out = {
'ip_pattern' : '%',
};
$scope.getList = function() {
$scope.data=IPService.getList($scope.data_out,
function(response) {
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
filter: {
id: '' // initial filter
},
sorting: {
id: 'asc' // initial sorting
}
}, {
total: response.list.length, // length of data
getData: function($defer, params) {
// use build-in angular filter
var filteredData = params.filter() ?
$filter('filter')(response.list, params.filter()) :
response.list;
var orderedData = params.sorting() ?
$filter('orderBy')(filteredData, params.orderBy()) :
response.list;
params.total(orderedData.length); // set total for recalc pagination
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
});
};
});
Here is html view
<table ng-table="tableParams" show-filter="true" class="table">
<tr ng-repeat="user in $data">
<td data-title="'Name'" sortable="'id'" filter="{ 'id': 'text' }">
{{user.id}}
</td>
<td data-title="'Age'" sortable="'value'" filter="{ 'value': 'text' }">
{{user.value}}
</td>
</tr>
</table>
There is a provided method to do just that:
$scope.tableParams.reload();
Just call it after you update the data the table is displaying.
Edit:
First off, I think your current use of ngTable is incorrect. Instead of tying the table directly to the response data, I think the best thing to do would be to store your response data in a $scope variable, and then attach it to your ngTable. That way you only have to manipulate the $scope data and call reload.
From there it is simply a matter of updating the stored data then calling reload:
// Store your data in a dedicated variable
$scope.myData = response.list;
// Update ngTable to reflect the new data
if ($scope.tableParams) {
$scope.tableParams.reload();
} else {
// create your table as before,
// but tying it to $scope.myData
// instead of response.list
}

angularJS with ng-table is not loading data on returning to listing from detail page

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.

Resources