Load data to dropdown in angularjs - angularjs

I am new to this angular js.
In my code a dropdown control has been loaded with some items, i know this list should be loaded from a xml file.
I want to know where/how it is been coded to load the data. Check this code and help me...
<select size="10" ng-model="model.addSelection" ng-options="a.name for a in availableList | availableList | propertyFilter:model.availableFilter" class="listBoxStyle" wat-focus/>
angular.module('readbackSelectModule', [])
.filter('availableList', [
function () {
return function (input) {
if (!angular.isArray(input)) return input;
var out = [];
for (var i = 0; i < input.length; i++) {
if (input[i].visible == true)
out.push(input[i]);
}
return out;
}
}
])
.filter('plotList', [
function () {
return function (input) {
if (!angular.isArray(input)) return input;
var out = [];
for (var i = 0; i < input.length; i++) {
if (input[i].visible == false)
out.push(input[i]);
}
return out;
}
}
])
.controller('readbackSelectCtrl', ['$scope', '$modalInstance', 'generalDataService', 'keyService', 'propertyFilterFilter', 'availableListFilter', 'plotListFilter', 'plotPanelService',
function ($scope, $modalInstance, generalDataService, keyService, propertyFilterFilter, availableListFilter, plotListFilter, plotPanelService) {
var CANCEL_MESSAGE = 'cancel';
var GET_DATA_MESSAGE = 'getdata';
var REQUEST_PROPERTY_LIST_MESSAGE = 'requestplotdata';
var SUBSCRIBE = 'plotsubscribe';
var UNSUBSCRIBE = 'plotunsubscribe';
var STREAM_TYPE = '4';
$scope.model = {};
$scope.model.addSelection;
$scope.model.removeSelection;
$scope.model.availableFilter;
// List of properties
$scope.availableList = [];
};

Use Angular's $http service.
You can do it in your readbackSelectCtrl, like this:
...
$scope.model = {};
$scope.model.addSelection;
$scope.model.removeSelection;
$scope.model.availableFilter;
$http.get(/** insert XML file URL here **/)
.success(function(data) {
// process the data and extract the XML elements you want
$scope.availableList = xmlExtractedArray;
})
.error(function(err) {
// handle error
});
Check this plunker for a working demo.

Related

How to initialize an angularJS factory with a button click

I have a factory to load data from an API. Code looks like
.factory('iScroll', function($http) {
var iScroll = function(pre_url){
this.items = [];
this.busy = false;
this.page = 1;
this.pre_url = pre_url;
}
iScroll.prototype.nextPage = function(){
if(this.busy) return;
this.busy = true;
var url = this.pre_url + 'page='+this.page;
$http.get(url).then(function(response){
console.log(response.data);
for (var i = 0; i < response.data.length; i++){
this.items.push(response.data[i]);
console.log("loading...");
}
this.page++;
this.busy = false;
}.bind(this));
};
return iScroll;
})
I initialize it like $scope.load_users = new iScroll('/api/web/branches/users/' +$stateParams.id+'?');
My question is, how can i call the factory via a button click?
In your template, you would use the ngClick directive to trigger an action:
<button type="button" ng-click="loadUsersAction()">Load Users</button>
Then in your controller, you define that function:
$scope.loadUsersAction = function() {
$scope.load_users = new iScroll('/api/web/branches/users/' +$stateParams.id+'?');
};

Highcharts send global data to angular controller

I've recently decided to use angular on a webpage, but having never used it before and being new to web dev I've run into some issues. The page has some highchart graphs where, upon clicking on a point triggers a modal with a table of data. This table is created with an angular controller.
Initially the table is empty because the user hasn't selected the data to populate it. So the data called: cases starts:var cases = []; and the controller initializes with: $scope.items = cases;
Here is where I get the data for the table:
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function () {
if (this.series.name == 'Work left')
{
cases = [];
//GET THE DATA
$.getJSON(uri + '/get?team=' + team + '&sprint=' + sprint + '&day=' + this.category)
.done(function (data) {
$.each(data, function (n, field) {
n++
cases.push({ "DT": field.dt, "Title": field.subject, "Type": field.type, "Est": field.est, "Product": field.Prod, "Sprint": field.Sprint, "Status": field.Status, "CreatedDate": field.cDate });
});
});
//UPDATE THE TABLE WITH NEW DATA HERE
$("#myModal").modal();//TRIGGER MODAL
}
}
}
}
}
}
In this highchart function I get the parameters: team,sprint and day based off of which point on which graph the user clicked. Then get the data from an api call.
What I want to know is if it's possible to "reinitialize" the angular controller at //UPDATE THE TABLE WITH NEW DATA HERE line, before triggering the modal. I need $scope.items = cases; but with cases being populated with the new data.
Basically I get the data dynamically with a highchart function, and I want to send this data to the angular controller where the table is updated, so that when I trigger the modal the table on it has the specified data.
Angular table controller:
var sortingOrder = 'CreatedDate'; //default sort
var app = angular.module("casetable", []);
app.controller('initApp', ['$scope', '$filter',
function ($scope, $filter) {
// init
$scope.sortingOrder = sortingOrder;
$scope.reverse = false;
$scope.filteredItems = [];
$scope.groupedItems = [];
$scope.itemsPerPage = 9;
$scope.pagedItems = [];
$scope.currentPage = 0;
$scope.items = cases;
var searchMatch = function (haystack, needle) {
if (!needle) {
return true;
}
return haystack.toLowerCase().indexOf(needle.toLowerCase()) !== -1;
};
// init the filtered items
$scope.search = function () {
$scope.filteredItems = $filter('filter')($scope.items, function (item) {
for (var attr in item) {
if (searchMatch(item[attr], $scope.query))
return true;
}
return false;
});
// take care of the sorting order
if ($scope.sortingOrder !== '') {
$scope.filteredItems = $filter('orderBy')($scope.filteredItems, $scope.sortingOrder, $scope.reverse);
}
$scope.currentPage = 0;
// now group by pages
$scope.groupToPages();
};
// show items per page
$scope.perPage = function () {
$scope.groupToPages();
};
// calculate page in place
$scope.groupToPages = function () {
$scope.pagedItems = [];
for (var i = 0; i < $scope.filteredItems.length; i++) {
if (i % $scope.itemsPerPage === 0) {
$scope.pagedItems[Math.floor(i / $scope.itemsPerPage)] = [$scope.filteredItems[i]];
} else {
$scope.pagedItems[Math.floor(i / $scope.itemsPerPage)].push($scope.filteredItems[i]);
}
}
};
$scope.deleteItem = function (idx) {
var itemToDelete = $scope.pagedItems[$scope.currentPage][idx];
var idxInItems = $scope.items.indexOf(itemToDelete);
$scope.items.splice(idxInItems, 1);
$scope.search();
return false;
};
$scope.range = function (start, end) {
var ret = [];
if (!end) {
end = start;
start = 0;
}
for (var i = start; i < end; i++) {
ret.push(i);
}
return ret;
};
$scope.prevPage = function () {
if ($scope.currentPage > 0) {
$scope.currentPage--;
}
};
$scope.nextPage = function () {
if ($scope.currentPage < $scope.pagedItems.length - 1) {
$scope.currentPage++;
}
};
$scope.setPage = function () {
$scope.currentPage = this.n;
};
// functions have been describe process the data for display
$scope.search();
// change sorting order
$scope.sort_by = function (newSortingOrder) {
if ($scope.sortingOrder == newSortingOrder)
$scope.reverse = !$scope.reverse;
$scope.sortingOrder = newSortingOrder;
};
}]);

AngularJS custom filter unknown provider error

I created this filter to transform userID to user's name:
angular.module('idToName', ['userService'])
.filter('idToName', function(User) {
User.allUsers()
.success(function(data) {
userData = data;
});
var assignee;
return function(IDs) {
for (var j = 0; j < userData.length; i++) {
for (var i = 0; i < IDs.length; j++){
if (IDs[i] == userData[j]._id) {
assignee[i] = userData[j].firstname + ' ' + userData[j].lastname + ' ' + userData[j].cname;
}
}
}
return assignee;
}
})
It takes in an array of userIDs, and it should find the corresponding userData object and return its names.
But when I run it, it gets this error:
Error: $injector:unpr
Unknown Provider
Unknown provider: idToNameFilterProvider
So what did I do wrong? I would appreciate any help.
Please check working demo: JSFiddle
angular.module('idToName', [])
.factory('userService', ['$http', function ($http) {
var users = [];
return {
all: function () {
return $http.get('http://jsonplaceholder.typicode.com/users');
}
};
}])
.filter('idToName', function () {
var assignee = [];
return function (userData, IDs) {
if (!userData || userData.length === 0) {
return 'loading...';
}
for (var i = 0; i < userData.length; i++) {
for (var j = 0; j < IDs.length; j++) {
if (IDs[j] == userData[i].id) {
assignee[i] = userData[i].name + ' ' + userData[i].username + ' ';
}
}
}
return assignee;
}
})
.controller('MyCtrl', ['$scope', 'userService', function ($scope, userService) {
$scope.IDs = [1, 2, 3, 4];
$scope.users = [];
userService.all().success(function (data) {
$scope.users = data;
});
}]);
Use it in HTML:
<div ng-app="idToName" ng-controller='MyCtrl'>{{ users | idToName:IDs }}</div>
Some issues in your code:
Your userData is obtained asyncly, when you call the filter, the userData may not have arrived yet. And your filter should not be fetching data. Because it is not its job. You'd better separate the data-fetching logic to some independent logic. So I created another service userService
You nested for loop is messed with the i and j variables. I have made them working.
idToName is not a good module name.
Update 1
Learned from comments of #tuckerjt07 and #ach, please check your JavaScript inclusion and module dependency code. There must be something wrong when trying to inject the filter. Seems the filter itself is not found within the context.

AngularJS custom filter don't receive data

I have a problem with a new filter which don't receive the data:
here my error log:
Controller Code:
angular.module('reklaApp')
.controller('MainCtrl', function ($scope, $http, Reklas, Modal) {
$scope.newRekla = {};
Reklas.getAll()
.success(function(data) {
$scope.reklas = data;
});
Filter Code:
angular.module('reklaApp')
.filter('dateFilter', function () {
return function (items) {
var filtered = [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
filtered.push(item);
}
return filtered;
};
});
HTML Code:
<tr ng-repeat="rekla in reklas | dateFilter">
<td>{{rekla.dt | date: 'dd.MM.yyyy'}}</td>
<td>{{rekla.order}}</td>
<td>{{rekla.personal}}</td>
<td>{{rekla.department}}</td>
<td>{{rekla.xyz}}</td>
<td>{{rekla.desc | limitTo: '50'}}</td>
<td>{{rekla.costs}}</td>
I think the "item" variable dont receive the data from the ng-repeat!?
It's because you didn't create it to begin with on your $scope. So since your getAll function takes some time the filter doesn't have the data. You can fix this two ways:
By first initializing the variable:
angular.module('reklaApp')
.controller('MainCtrl', function ($scope, $http, Reklas, Modal) {
$scope.newRekla = {};
$scope.reklas = [];
Reklas.getAll()
.success(function(data) {
$scope.reklas = data;
});
Or by updating your filter:
angular.module('reklaApp')
.filter('dateFilter', function () {
return function (items) {
if(!angular.isArray(items)){ return items }
var filtered = [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
filtered.push(item);
}
return filtered;
};
});

AngularJS paging

I made AngularJS pagination with spring mvc It works well ,but the application get a large amount of data from database so the application is very slow when I get first page because it get all records,Can anyone help me to solve this problem?I want to get subset of data from database depending on angularJS pagination
Spring mvc Controlller
#RequestMapping(value = "/rest/contacts",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public List<Contact> getAll() {
return contactRepository.findAll();
}
AngularJS Service
pagingpocApp.factory('Contact', function ($resource) {
return $resource('app/rest/contacts/:id', {}, {
'query': { method: 'GET', isArray: true},
'get': { method: 'GET'}
});
});
AngularJS Controller
pagingpocApp.controller('ContactController', function ($scope, $filter,resolvedContact, Contact, resolvedRole) {
$scope.contacts = resolvedContact;
var sortingOrder = 'firstName';
$scope.sortingOrder = sortingOrder;
$scope.reverse = false;
$scope.filteredItems = [];
$scope.groupedItems = [];
$scope.itemsPerPage = 10;
$scope.pagedItems = [];
$scope.currentPage = 0;
var searchMatch = function (haystack, needle) {
if (!needle) {
return true;
}
return haystack.toLowerCase().indexOf(needle.toLowerCase()) !== -1;
};
// init the filtered items
$scope.search = function () {
$scope.filteredItems = $filter('filter')($scope.contacts, function (item) {
for(var attr in item) {
if (searchMatch(item[attr], $scope.query))
return true;
}
return false;
});
// take care of the sorting order
if ($scope.sortingOrder !== '') {
$scope.filteredItems = $filter('orderBy')($scope.filteredItems, $scope.sortingOrder, $scope.reverse);
}
$scope.currentPage = 0;
// now group by pages
$scope.groupToPages();
};
// calculate page in place
$scope.groupToPages = function () {
$scope.pagedItems = [];
for (var i = 0; i < $scope.filteredItems.length; i++) {
if (i % $scope.itemsPerPage === 0) {
$scope.pagedItems[Math.floor(i / $scope.itemsPerPage)] = [ $scope.filteredItems[i] ];
} else {
$scope.pagedItems[Math.floor(i / $scope.itemsPerPage)].push($scope.filteredItems[i]);
}
}
};
$scope.range = function (start, end) {
var ret = [];
if (!end) {
end = start;
start = 0;
}
for (var i = start; i < end; i++) {
ret.push(i);
}
return ret;
};
$scope.prevPage = function () {
if ($scope.currentPage > 0) {
$scope.currentPage--;
}
};
$scope.nextPage = function () {
if ($scope.currentPage < $scope.pagedItems.length - 1) {
$scope.currentPage++;
}
};
$scope.setPage = function () {
$scope.currentPage = this.n;
};
// functions have been describe process the data for display
$scope.search();
// change sorting order
$scope.sort_by = function(newSortingOrder) {
if ($scope.sortingOrder == newSortingOrder)
$scope.reverse = !$scope.reverse;
$scope.sortingOrder = newSortingOrder;
// icon setup
$('th i').each(function(){
// icon reset
$(this).removeClass().addClass('icon-sort');
});
if ($scope.reverse)
$('th.'+new_sorting_order+' i').removeClass().addClass('icon-chevron-up');
else
$('th.'+new_sorting_order+' i').removeClass().addClass('icon-chevron-down');
};
});
One quick option would be to create a get method on your API that only returns a subset of the data, maybe only 25 contacts at a time, or a page or two worth of data. Then you could create a service in angular that makes that get call every 3 seconds or so to get the next 25 contacts. A sort of lazy loading technique.
Ben Nadel does a great job in this article of outlining how his company handles large sets of images being loaded to a page using a lazy loading technique. Reading through his example could give you a nice starting point.
Edit: I'm also going to recommend you refer to this solution for an answer slightly more on point to what you're looking to achieve. He recommends pushing data to your controller as soon as it's found:
function MyCtrl($scope, $timeout, $q) {
var fetchOne = function() {
var deferred = $q.defer();
$timeout(function() {
deferred.resolve([random(), random() + 100, random() + 200]);
}, random() * 5000);
return deferred.promise;
};
$scope.scans = [];
for (var i = 0; i < 2; i++) {
fetchOne().then(function(items) {
angular.forEach(items, function(item) {
$scope.scans.push(item);
});
});
};
}

Resources