smart-table slow performance while displaying large data set - javascript

Im trying to display large data set using smart-table. Im contacting server with $http request and when I assign response data to $scope.rowCollection, application stuck for nearly 40 second until all data is displayed on page. In response json i got nearly 18000 results to display. I dont know if I do something wrong. I get response from server in 600 ms but after assign application stuck. It looks like smart-table is trying to make a copy of response in displayedCollection array and this operation take long time but its only my opinion. Please help. Thanks in advance.
HTML
<table st-table="displayedCollection" st-safe-src="rowCollection" class="table">
<thead>
<tr>
<th colspan="8"><input st-search="" class="form-control" placeholder="global search ..." type="text" /></th>
</tr>
<tr>
<th st-sort="TestEndDate">Test Date</th>
<th st-sort="Workplace">Workplace</th>
<th st-sort="Tester">Worker</th>
<th st-sort="SerialNo">Serial Number</th>
<th st-sort="TestProgram">Testing program</th>
<th st-sort="TestResult">Test Result</th>
<th>Download</th>
<th>Detail</th>
</tr>
</thead>
<tbody>
<tr st-select-row="row" st-select-mode="multiple" ng-repeat="row in displayedCollection">
<td>{{row.TestEndDate | date}}</td>
<td>{{row.Workplace}}</td>
<td>{{row.Tester}}</td>
<td>{{row.SerialNo}}</td>
<td>{{row.TestProgram}}</td>
<td>{{row.TestResult}}</td>
<td>
<button type="button" ng-click="downloadItem(row)" class="btn btn-sm btn-success">
<i class="glyphicon glyphicon-download">
</i>
</button>
</td>
<td>
<button type="button" ng-click="detailItem(row)" class="btn btn-sm btn-primary">
<i class="glyphicon glyphicon-eye-open">
</i>
</button>
</td>
</tr>
</tbody>
</table>
Javascript
app.controller('AppController', ['$scope', '$http', '$modal', function ($scope, $http, $modal) {
var search = this;
search.serials = [];
$scope.rowCollection = [];
$scope.init = function () {
waitingDialog.show();//show loading
getTestResults();
};
var getTestResults = function () {
$http({
method: 'GET',
url: "http://sqldev/api/testresults"
}).then(function successCallback(response) {
$scope.rowCollection = response.data;//after assign response.data into rowCollection application stuck
waitingDialog.hide();//hide loading
}, function errorCallback(response) {
console.log('Error: ' + response);
waitingDialog.hide();//hide loading
$scope.open()//open modal with error message
});
};
}]);

Related

AngularJs ng-click function getting runtime error - can't read property of undefined

Hi i am trying to run a function from my .js file by a button but when i click the button it is not responding and nothing is happening.
Html:
<html>
<head>
<script src = "groups.js"></script>
</head>
<body>
<div ng-app="myApp">
<div ng-controller="groupsCtrl">
<div class="group-jumbotron">
<h1 class="display-4">Champion's League Groups</h1>
<p class="lead">The 2018–19 UEFA Champions League group stage began on 18 September and is scheduled to end on 12 December 2018. <br/>
A total of 32 teams compete in the group stage to decide the 16 places in the knockout phase of the 2018–19 UEFA Champions League.
</p>
<hr class="my-1">
<p>Information about each group can be seen below</p>
</div>
<div class="addGroup-Title">
<h4 class="display-6">Groups:</h4>
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">Group Letter</th>
<th scope="col">Number of Teams</th>
<th scope="col">Matches Played</th>
<th scope="col">Top Goalscorer</th>
<th scope="col">Top Assists</th>
<th scope="col">Most Cards</th>
<th scope="col">Total Points</th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="group in leagueGroup">
<td>{{group.groupLetter}}</td>
<td>{{group.numberOfTeams}}</td>
<td>{{group.totalMatchesPlayed}}</td>
<td>{{group.topGoalscorer}}</td>
<td>{{group.topAssists}}</td>
<td>{{group.mostCards}}</td>
<td>{{group.totalPoints}}</td>
<td><button type="submit" class="btn btn-outline-info" ng-click="getSpecificGroup()">Edit</button></td>
//THIS BUTTON
<td><button type="button" class="btn btn-outline-danger"
ng-click="deleteGroupById()">Delete</button></td>
</tr>
</tbody>
</table>
</div>
.js file:
'use strict';
angular.module('myApp.groups', ['ngRoute'])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/groups', {
templateUrl: 'groups/groups.html',
controller: 'groupsCtrl'
});
}])
.controller('groupsCtrl', function ($scope, $http) {
$scope.deleteGroupById = function () {
const isConfirmed = window.confirm('Are you sure you want to delete Group: ' + $scope.groupData.groupId + '?');
if (isConfirmed) {
$http.get('http://localhost:5000/api/v1/groups/' + $scope.leagueGroup.groupId)
.then(function (response) {
$scope.groupData = response.data;
});
$http.delete('http://localhost:5000/api/v1/groups/' + $scope.groupData.groupId)
.then(function (response) {
$scope.response = response.data;
alert('Group deleted successfully: ' + $scope.groupData.groupId);
},
function (error) {
alert("Error! Group could not be deleted!" + $scope.groupData.groupId);
});
}
};
});
function getgroupId() {
return Math.floor((Math.random() * 9999) + 10);
}
Chrome Inspector:
TypeError: Cannot read property 'groupId' of undefined
at b.$scope.deleteGroupById (groups.js:74)
at fn (eval at compile (angular.js:16387), <anonymous>:4:165)
at e (angular.js:28815)
at b.$eval (angular.js:19356)
at b.$apply (angular.js:19455)
at HTMLButtonElement.<anonymous> (angular.js:28819)
at og (angular.js:3805)
at HTMLButtonElement.d (angular.js:3793)
So it should be calling the $scope.deleteGroupById() but unfortunately it is just doing nothing??
I have used buttons used submit buttons that work and have also tried to place the button outside of the table but it still does not seem to be responding
does anyone have any ideas?
When you are using ng-repeat you must send propriety to your function so the controller sees what propriety to use. The other mistake is that you tried to access your response before $http finish the request.
<tr ng-repeat="group in leagueGroup">
<td>{{group.groupLetter}}</td>
<td>{{group.numberOfTeams}}</td>
<td>{{group.totalMatchesPlayed}}</td>
<td>{{group.topGoalscorer}}</td>
<td>{{group.topAssists}}</td>
<td>{{group.mostCards}}</td>
<td>{{group.totalPoints}}</td>
<td><button type="submit" class="btn btn-outline-info" ng-click="getSpecificGroup(group)">Edit</button></td> <!-- Send the group to function -->
//THIS BUTTON
<td><button type="button" class="btn btn-outline-danger"
ng-click="deleteGroupById(group)">Delete</button></td> <!-- Send the group to function -->
</tr>
And JS
// Width group parameter
$scope.deleteGroupById = function (group) {
const isConfirmed = window.confirm('Are you sure you want to delete Group: ' + group.groupId + '?');
if (isConfirmed) {
$http.get('http://localhost:5000/api/v1/groups/' + group.groupId)
.then(function (response) {
$scope.groupData = response.data;
// Delete when you get your response
$http.delete('http://localhost:5000/api/v1/groups/' + $scope.groupData.groupId)
.then(function (response) {
$scope.response = response.data;
alert('Group deleted successfully: ' + $scope.groupData.groupId);
},
function (error) {
alert("Error! Group could not be deleted!" + $scope.groupData.groupId);
});
});
}
};

Angular JS Display Response Values

I'm trying to display data from one page to another in Angular JS. Using displayResponse in Firefoxes Console, the Response data seems to be retrieved however I'm having trouble trying to display the values on the page which is troublesome since a Team member was able to get them to display properly on other pages on the site.
Here is the Code so far (I have removed chucks of the script to save screen space. These bits of code are not relevant to the issue afaik):
var app = angular.module("myApp", ['ngRoute']);
app.config(function($routeProvider) {
$routeProvider
.when('/ViewSalesRecords', {
templateUrl: 'view-sales-records.html',
controller: 'salesRecordController'
}).
when('/ViewSingleSale', {
templateUrl: 'view-single-sale.html',
controller: 'salesRecordController'
});
});
app.controller('salesRecordController', ['$scope', '$http', function($scope, $http) {
$scope.displaySingleSale = function(sale_id) {
$http.post('read_sale.php', {
'sale_id': sale_id
})
.then(function(response) {
$scope.singleSalesRecord = response.data;
console.log($scope.singleSalesRecord);
})
}
$http.get("read_sale.php")
.then(
function(response) {
$scope.salesRecords = response.data;
}
)
}]);
<head>
<link href="./styles/style.css" rel="stylesheet">
</head>
<table class="table table-hover" data-ng-model="sale_id">
<p><strong>Sale ID: {{displayResponse}} </strong> </p>
<p><strong>Sale Date: </strong> </p>
<thead>
<tr>
<th>Product ID</th>
<th>Product Name</th>
<th>Quantity</th>
<th>Item Total</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="s in singleSalesRecord">
<td>{{s.product_id}}</td>
<td>{{s.product_name}}</td>
<td>{{s.quantity}}</td>
<td>${{s.product_price}}</td>
</tr>
</tbody>
</table>
<p><strong>Total: ${{s.orderTotal}}</strong></p>
The page that is sending the data
<head>
<link href="./styles/style.css" rel="stylesheet">
</head>
<div>
<input class="form-control searchBar" data-ng-model="searchText.sale_id" type="text" placeholder="Search sales by Sale ID">
<table class="table table-hover">
<thead>
<tr>
<th>Sale ID</th>
<th>Total items</th>
<th>Total price</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="s in salesRecords | filter:searchText:strict">
<td>{{s.sale_id}}</td>
<td>{{s.TotalItems}}</td>
<td>${{s.orderTotal}}</td>
<td>
<button class="btn btn-primary">View</button>
<button class="btn btn-danger">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
So wall of text taken into consideration, what am I doing wrong? I will admit I'm not too familiar with AngularJS so this might be a very amateur mistake on my part.
I figured out that the problem was that the values that I wanted to transfer were been wiped when I moved to another page. So I decided to simply display them on the first page instead hyperlinking to another.

Displaying JSON content in table rows using angularjs and codeigniter

I'm just trying to fetch contents from server and display it in a table using Angularjs. I'm been trying this from a while, but did not got any solution yet. Btw, I'm working on CodeIgniter framework.
Here is my CodeIgniter controller;
public function list_agents() {
if($this->is_logged_in ()) {
$agents = $this->generic_model->general_fetch('agent_master');
echo json_encode($agents);
}
else {
redirect(base_url());
}
}
In the above code, instead of echo I used print, print_r also.. But still its not working.
Here is my js file function;
(function () {
var addApp = angular.module('agentApp', ['ngRoute']);
addApp.controller('agentAddController', function ($scope, $http, growl) {
$scope.receivedData = [];
$http({
method : 'POST',
url : 'agent/list_agents',
headers : {
"Content-Type" : "application/json"
}
}).then(function (data) {
$scope.receivedData = JSON.parse(data);
});
});
})();
And in this above code I used with and without JSON.parse function. Didn't got the correct result.
Here is my view;
<section class="content" ng-app="agentApp" ng-controller="agentAddController">
<div class="row">
<div class="col-md-12">
<div class="box box-info">
<div class="box-header with-border">
<h3 class="box-title">Manage Agents</h3>
</div>
<div class="box-body">
<table class="table table-striped table-bordered" id="agents_table">
<thead>
<tr>
<th>Sl No.</th>
<th>Agent Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<div ng-repeat="data in receivedData">
<tr>
<td>{{ $index + 1 }}</td>
<td>{{ data.agent_name }}</td>
<td><button class="btn btn-warning btn-xs"><i class="fa fa-trash" aria-hidden="true"></i></button></td>
</tr>
</div>
</tbody>
<tfoot>
<tr>
<th>Sl No.</th>
<th>Agent Name</th>
<th>Actions</th>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
</section>
I know if I put ng-repeat inside tr tag I'll get the perfect result, but I don't want to do that because, I'm working with adminLTE. So there is a function DataTable() in adminLTE where it'll apply search and pagination to the table. If I give ng-repeat to tr, these functionalities can not be added.
Try: $scope.receivedData = JSON.parse(data.data);
The response object is not only the data itself, that's why the 5 rows. It gives back, data, headers, status, etc...
https://docs.angularjs.org/api/ng/service/$http

AngularJS: new object not showing in table

I am using dir-paginate library to paginate my data on the page. The issue I am having is when I am adding a new object to the list and viewing this on the page instantly. On the controller side every thing seems to work just alright.
Here is my controller
/**
* Array of all the items
*/
$scope.allItems = [];
$scope.postResource = function() {
ProjectsFactory.save($scope.newProject)
.success(function(data) {
$scope.allItems.push(data);
console.log($scope.allItems);
$scope.newProject = ''
ToastService.show('Added successfully!');
})
.error(function(data) {
sweetAlert("Oops...", "Something went wrong!", "error");
console.log(data);
});
}
Notice the log I am doing right there. On the console page I can see the new object is being added to the rest of the objects. I believe the issue is occurring on the view side which looks just like this.
<table class="table table-bordered table-hover table-condensed bg-white" st-table="rowCollectionBasic">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr dir-paginate="item in allItems | filter: search.query | itemsPerPage : itemPerPage" total-items="totalProjects" current-page="currentPage">
<td>{{item.name}}</td>
<td>{{item.description}}</td>
<td style="width:150px">
<button class="btn btn-info btn-sm" ng-click="showEditDialog($event, item)">
<i class="glyphicon glyphicon-edit"></i>
</button>
<button class="btn btn-danger btn-sm" ng-click="deleteResource(item, $index)">
<i class="glyphicon glyphicon-trash"></i>
</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="20" class="text-center">
<dir-pagination-controls on-page-change="pageChanged(newPageNumber)" boundary-links="true"></dir-pagination-controls>
<md-progress-circular md-mode="indeterminate" ng-if="AjaxInProgress"></md-progress-circular>
</td>
</tr>
</tfoot>
To see the new created object on the page, I need to either refresh the page or click somewhere else and return to the same page again.
Someone has an idea what I am doing wrong?
Update #1
The project service has $http
// save a new resource
save: function(data) {
return $http({
url: $rootScope.baseUrl + 'projects',
method: 'POST',
data: data
});
},
Thanks!

How to edit contents in Angular js Smart Table

I am quite new to java script, so I must apologise if this seems basic.
How can I edit rows tables in Smart-Table with Angularjs? There doesn't seem to be a tutorial with the new Smart-Table. I would like to create a simple form for users to enter the hours open for a particular place.
I have created buttons which can add and remove rows on the table, but when I add in contenteditable="true" none of the changes are persisted when I update the object. I understand that the contenteditable is a specific html5 parameters independent of smart-table, but I don't understand how else I can update the data or how I could retrieve the updated data.
The data is retrieved from the angularjs controller via the mean.js routes.
<div class="controls">
<table st-table="place.openHours" class="table table-striped">
<thead>
<tr>
<th>Day</th>
<th>Opening Time</th>
<th>Closing Time</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in place.openHours" contenteditable="true" >
<td>{{row.day}}</td>
<td>{{row.open}}</td>
<td>{{row.close}}</td>
<button type="button" ng-click="removeOpenHour(row)" class="btn btn-sm btn-danger">
<i class="glyphicon glyphicon-remove-circle">
</i>
</button>
</tr>
</tbody>
</table>
<button type="button" ng-click="addOpenHour(row)" class="btn btn-sm btn-success">
<i class="glyphicon glyphicon-plus">
</i> Add new Row
</button>
</div>
Inside the javascript:
$scope.removeOpenHour = function removeOpenHour(row) {
var index = $scope.place.openHours.indexOf(row);
if (index !== -1) {
$scope.rowCollection.splice(index, 1);
}
}
$scope.addOpenHour = function addOpenHour() {
$scope.place.openHours.push(
{
day: 'Monday',
open: 540,
close: 1080
});
};
Thanks I had a look around and used the code from here http://jsfiddle.net/bonamico/cAHz7/ and merged it with my code.
HTML file:
<tr ng-repeat="row in place.openHours">
<td><div contentEditable="true" ng-model="row.day">{{row.day}}</div></td>
<td><div contentEditable="true" ng-model="row.open">{{row.open}}</div></td>
<td><div contentEditable="true" ng-model="row.close">{{row.close}}</div></td>
<td>
<button type="button" ng-click="removeOpenHour(row)" class="btn btn-sm btn-danger">
<i class="glyphicon glyphicon-remove-circle">
</i>
</button>
</td>
JS file:
myApp.directive('contenteditable', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
// view -> model
elm.bind('blur', function() {
scope.$apply(function() {
ctrl.$setViewValue(elm.html());
});
});
// model -> view
ctrl.render = function(value) {
elm.html(value);
};
elm.bind('keydown', function(event) {
console.log("keydown " + event.which);
var esc = event.which == 27,
el = event.target;
if (esc) {
console.log("esc");
ctrl.$setViewValue(elm.html());
el.blur();
event.preventDefault();
}
});
}
};
});
My solution is it:
Angular directive :
app.directive("markdown", function() {
return {
restrict: 'EA',
scope: {
value: '='},
template: '<span ng-click="edit()" ng-bind="value"></span><input ng-blur="blur()" ng-model="value"></input>',
link: function($scope, element, attrs) {
// Let's get a reference to the input element, as we'll want to reference it.
var inputElement = angular.element(element.children()[1]);
// This directive should have a set class so we can style it.
element.addClass('edit-in-place');
// Initially, we're not editing.
$scope.editing = false;
// ng-click handler to activate edit-in-place
$scope.edit = function() {
$scope.editing = true;
// We control display through a class on the directive itself. See the CSS.
element.addClass('active');
// And we must focus the element.
// `angular.element()` provides a chainable array, like jQuery so to access a native DOM function,
// we have to reference the first element in the array.
inputElement[0].focus();
};
// When we leave the input, we're done editing.
$scope.blur = function() {
$scope.editing = false;
element.removeClass('active');
}
}
};
});
HTML:
<table st-table="displayedCollection" st-safe-src="rowCollection" class="table table-striped">
<thead>
<tr>
<th st-sort="sku">SKU</th>
<th st-sort="skuSupplier">SKU proveedor</th>
<th st-sort="name">Descripción</th>
<th st-sort="cantidad">Cantidad</th>
<th st-sort="precio">Precio unitario</th>
<th st-sort="total">Total</th>
</tr>
<tr>
<th colspan="5"><input st-search="" class="form-control" placeholder="Buscar producto ..." type="text"/></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in displayedCollection">
<td><markdown value="row.sku"></markdown></td>
<td><markdown value="row.skuSupplier"></markdown></td>
<td><markdown value="row.name"></markdown></td>
<td><markdown value="row.cantidad"></markdown></td>
<td><markdown value="row.precio"></markdown></td>
<td><markdown value="row.total"></markdown></td>
<td>
<button type="button" ng-click="removeItem(row)" class="btn btn-sm btn-danger">
<i class="glyphicon glyphicon-remove-circle"></i>
</button>
</td>
</tr>
</tbody>
</table>

Categories

Resources