not able to call factory at controller - angularjs

I have created a factory named paging that will return numbers for pagination.
expenseApp.factory('paging', function() {
this.pages = function(min, max, step) {
if (max <= 5) {
min = 1;
}
if (max > 5) {
min = max - 3;
}
step = step || 1;
var input = [];
for (var i = min; i <= max; i += step)
input.push(i);
return input;
};
I want to call this factory in my controller
expenseApp.controller('expenseController', function($scope, $http, paging) {
$scope.range = function() {
$scope.answer = paging.range(0, 10, 1);
}
});
but this code is not working.
I tried it here
var expenseApp = angular.module('expenseApp', []);
expenseApp.factory('paging', function() {
this.pages = function(min, max, step) {
if (max <= 5) {
min = 1;
}
if (max > 5) {
min = max - 3;
}
step = step || 1;
var input = [];
for (var i = min; i <= max; i += step)
input.push(i);
return input;
};
expenseApp.controller('expenseController', function($scope, $http, paging) {
$scope.pages = function() {
$scope.answer = paging.range(0, 10,1);
}
});
});
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js"></script>
<link rel="stylesheet" href="style.css">
<script src="MyApp.js"></script>
<script src="MyCtrl.js"></script>
</head>
<body>
<div ng-app="expenseApp" ng-controller="expenseController">
<h1>Hello Plunker!</h1>
<ul class="pagination">
<li ng-repeat="a in pages">
<a ng-click="pagination(a)">{{a}}</a>
</li>
</ul>
</div>
</body>
</html>

var expenseApp = angular.module('expenseApp', []);
expenseApp.factory('paging', function() {
return {
pages: function(min, max, step) {
if (max <= 5) {
min = 1;
}
if (max > 5) {
min = max - 3;
}
step = step || 1;
var input = [];
for (var i = min; i <= max; i += step)
input.push(i);
return input;
}
}
});
expenseApp.controller('expenseController', ['$scope', '$http', 'paging', function($scope, $http, paging) {
$scope.pages = function() {
$scope.answer = paging.pages(0, 10, 1);
}
$scope.pages();
}]);
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js"></script>
</head>
<body>
<div ng-app="expenseApp" ng-controller="expenseController">
<h1>Hello Plunker!</h1>
<ul class="pagination">
<li ng-repeat="a in answer">
<a ng-click="pagination(a)">{{a}}</a>
</li>
</ul>
</div>
</body>
</html>
Kindly check this snippet.
Changes I made:
index.html
<script src="MYApp.js"></script>
<ul class="pagination">
<li ng-repeat="a in answer">
<a ng-click="pagination(a)">{{a}}</a>
</li>
</ul>
MyCtrl.js
expenseApp.factory('paging', function() {
return {
pages: function(min, max, step) {
if (max <= 5) {
min = 1;
}
if (max > 5) {
min = max - 3;
}
step = step || 1;
var input = [];
for (var i = min; i <= max; i += step)
input.push(i);
return input;
}
}
});
expenseApp.controller('expenseController', ['$scope','$http', 'paging', function($scope, $http, paging) {
$scope.pages = function() {
console.log(paging)
$scope.answer = paging.pages(0, 10,1);
}
$scope.pages();
}]);

This is because you are getting error
Error: [$injector:undef] http://errors.angularjs.org/1.6.5/$injector/undef?p0=paging(…)
Which means that your factory is not returning any values. So, to resolve this you can use this code in your factory
expenseApp.factory('paging', function() {
var paging = {};
var range = function(min, max, step) {
if (max <= 5) {
min = 1;
}
if (max > 5) {
min = max - 3;
}
step = step || 1;
var input = [];
for (var i = min; i <= max; i += step)
input.push(i);
return input;
};
paging.range = range;
return paging;
});
Notice that var paging = {}; is a JSON object that will hold all the functionality provided by this factory like range so paging.range = range; will add a factory method range to the range key of the paging object. Then finally this object is returned from the service.
Now whenever you use the factory paging, then it is similar to using the JSON object paging. Thus, access paging.range(0, 10,1) will now invoke the factory method.
Your plunkr also does not work so here is the link to the working PLUNKR

Related

Obtaining the index of the top visible element of a list of items with ui-grid

Is it possible to obtain the index of the top element of a ui-grid that is currently visible/displayed by the client/browser?
For example, take a look at (an edited) ui-grid's infinite scrolling example in this plunkr example. Is it possible to obtain that that top index somehow?
This would be the app.js code, which is exactly the same as the infinite-scroll example:
var app = angular.module('app', ['ngTouch', 'ui.grid', 'ui.grid.infiniteScroll']);
app.controller('MainCtrl', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) {
$scope.gridOptions = {
infiniteScrollRowsFromEnd: 40,
infiniteScrollUp: true,
infiniteScrollDown: true,
columnDefs: [
{ name:'id'},
{ name:'name' },
{ name:'age' }
],
data: 'data',
onRegisterApi: function(gridApi){
gridApi.infiniteScroll.on.needLoadMoreData($scope, $scope.getDataDown);
gridApi.infiniteScroll.on.needLoadMoreDataTop($scope, $scope.getDataUp);
$scope.gridApi = gridApi;
}
};
$scope.data = [];
$scope.firstPage = 2;
$scope.lastPage = 2;
$scope.getFirstData = function() {
return $http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pageshttps://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/10000_complex.json')
.then(function(response) {
var newData = $scope.getPage(response.data, $scope.lastPage);
$scope.data = $scope.data.concat(newData);
});
};
$scope.getDataDown = function() {
return $http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pageshttps://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/10000_complex.json')
.then(function(response) {
$scope.lastPage++;
var newData = $scope.getPage(response.data, $scope.lastPage);
$scope.gridApi.infiniteScroll.saveScrollPercentage();
$scope.data = $scope.data.concat(newData);
return $scope.gridApi.infiniteScroll.dataLoaded($scope.firstPage > 0, $scope.lastPage < 4).then(function() {$scope.checkDataLength('up');});
})
.catch(function(error) {
return $scope.gridApi.infiniteScroll.dataLoaded();
});
};
$scope.getDataUp = function() {
return $http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pageshttps://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/10000_complex.json')
.then(function(response) {
$scope.firstPage--;
var newData = $scope.getPage(response.data, $scope.firstPage);
$scope.gridApi.infiniteScroll.saveScrollPercentage();
$scope.data = newData.concat($scope.data);
return $scope.gridApi.infiniteScroll.dataLoaded($scope.firstPage > 0, $scope.lastPage < 4).then(function() {$scope.checkDataLength('down');});
})
.catch(function(error) {
return $scope.gridApi.infiniteScroll.dataLoaded();
});
};
$scope.getPage = function(data, page) {
var res = [];
for (var i = (page * 100); i < (page + 1) * 100 && i < data.length; ++i) {
res.push(data[i]);
}
return res;
};
$scope.checkDataLength = function( discardDirection) {
// work out whether we need to discard a page, if so discard from the direction passed in
if( $scope.lastPage - $scope.firstPage > 3 ){
// we want to remove a page
$scope.gridApi.infiniteScroll.saveScrollPercentage();
if( discardDirection === 'up' ){
$scope.data = $scope.data.slice(100);
$scope.firstPage++;
$timeout(function() {
// wait for grid to ingest data changes
$scope.gridApi.infiniteScroll.dataRemovedTop($scope.firstPage > 0, $scope.lastPage < 4);
});
} else {
$scope.data = $scope.data.slice(0, 400);
$scope.lastPage--;
$timeout(function() {
// wait for grid to ingest data changes
$scope.gridApi.infiniteScroll.dataRemovedBottom($scope.firstPage > 0, $scope.lastPage < 4);
});
}
}
};
$scope.reset = function() {
$scope.firstPage = 2;
$scope.lastPage = 2;
// turn off the infinite scroll handling up and down - hopefully this won't be needed after #swalters scrolling changes
$scope.gridApi.infiniteScroll.setScrollDirections( false, false );
$scope.data = [];
$scope.getFirstData().then(function(){
$timeout(function() {
// timeout needed to allow digest cycle to complete,and grid to finish ingesting the data
$scope.gridApi.infiniteScroll.resetScroll( $scope.firstPage > 0, $scope.lastPage < 4 );
});
});
};
$scope.getFirstData().then(function(){
$timeout(function() {
// timeout needed to allow digest cycle to complete,and grid to finish ingesting the data
// you need to call resetData once you've loaded your data if you want to enable scroll up,
// it adjusts the scroll position down one pixel so that we can generate scroll up events
$scope.gridApi.infiniteScroll.resetScroll( $scope.firstPage > 0, $scope.lastPage < 4 );
});
});
}]);
HTML
<!doctype html>
<html ng-app="app">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-touch.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-animate.js"></script>
<script src="http://ui-grid.info/docs/grunt-scripts/csv.js"></script>
<script src="http://ui-grid.info/docs/grunt-scripts/pdfmake.js"></script>
<script src="http://ui-grid.info/docs/grunt-scripts/vfs_fonts.js"></script>
<script src="http://ui-grid.info/release/ui-grid.js"></script>
<link rel="stylesheet" href="http://ui-grid.info/release/ui-grid.css" type="text/css">
<link rel="stylesheet" href="main.css" type="text/css">
</head>
<body>
<div ng-controller="MainCtrl">
<button id="reset" class="button" ng-click="reset()">Reset</button>
<span> First page: {{ firstPage }} Last page: {{ lastPage }} data.length: {{ data.length }} </span>
<div ui-grid="gridOptions" class="grid" ui-grid-infinite-scroll></div>
</div>
<script src="app.js"></script>
</body>
</html>
Have a look at this npm package:
Once installed:
<ul style="width: 200px; height: 200px" viewport>
<li ng-repeat="item in items" style="width: 200px; height: 200px" viewport-leave="item.visible = false" viewport-enter="item.visible = true">
</ul>

Argument 'CarouselDemoCtrl' is not a function, got undefined

indexCtrl.js
var app = angular.module('app', ['ui.router', 'ui.bootstrap', 'ngAnimate'])
.config(['$urlRouterProvider', '$stateProvider', function($urlRouterProvider, $stateProvider) {
$scope.myInterval = 5000;
$scope.noWrapSlides = false;
$scope.active = 0;
var slides = $scope.slides = [];
var currIndex = 0;
$scope.addSlide = function() {
$http.get('/find').success(function(data) {
for (var i = 0; i < data.length; i++) {
var discovery = {};
discovery.image = data[i].image;
discovery.name = data[i].name;
discovery.objectType = data[i].objectType;
discovery.description = data[i].description;
discovery.discoveredBy = data[i].user;
discovery.discoveredOn = data[i].discoveredOn;
discovery.location = data[i].location;
$scope.discoveries.push(discovery);
} // end of for loop
for (var i = 0, i < 4, i++) {
var discovery = {};
var randNum = Math.floor(Math.random() * discoveries.length);
slides.push({
image = discoveries[randNum].image;
name = discoveries[randNum].name;
objectType = discoveries[randNum].objectType;
description = discoveries[randNum].description;
discoveredBy = discoveries[randNum].user;
discoveredOn = discoveries[randNum].discoveredOn;
location = discoveries[randNum].location;
});
}
});
// var newWidth = 600 + slides.length + 1;
// slides.push({
// image: '//unsplash.it/' + newWidth + '/300',
// // image: '../../images/jumbotron.jpg',
// text: ['Nice image','Awesome photograph','That is so cool','I love that'][slides.length % 4],
// id: currIndex++
// });
};
$scope.randomize = function() {
var indexes = generateIndexesArray();
assignNewIndexesToSlides(indexes);
};
for (var i = 0; i < 4; i++) {
$scope.addSlide();
}
// Randomize logic below
function assignNewIndexesToSlides(indexes) {
for (var i = 0, l = slides.length; i < l; i++) {
slides[i].id = indexes.pop();
}
}
function generateIndexesArray() {
var indexes = [];
for (var i = 0; i < currIndex; ++i) {
indexes[i] = i;
}
return shuffle(indexes);
}
// http://stackoverflow.com/questions/962802#962890
function shuffle(array) {
var tmp, current, top = array.length;
if (top) {
while (--top) {
current = Math.floor(Math.random() * (top + 1));
tmp = array[current];
array[current] = array[top];
array[top] = tmp;
}
}
return array;
}
}]);
I am trying to grab information from my database and use four random objects in the demo carousel instead of what angular ui bootstrap has for their demo.
I am currently getting this error: "Argument 'CarouselDemoCtrl' is not a function, got undefined" when I use my current $scope.addSlide function. However, it does not throw any errors and works fine when I have the commented out section in $scope.addSlide function instead. Why would this effect my CarouselfDemoCtrl in a way to make it not a function and how might I go about fixing it? Again, the carousel was working until I changed the $scope.addSlide function.
This is my app.js:
var app = angular.module('app', ['ui.router', 'ui.bootstrap', 'ngAnimate'])
.config(['$urlRouterProvider', '$stateProvider', function($urlRouterProvider, $stateProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('profile', {
url: '/profile',
templateUrl: 'views/profile.html',
controller: 'profileCtrl'
})
.state('discover', {
url: '/discover',
templateUrl: 'views/discover.html',
controller: 'discoverCtrl'
})
.state('find', {
url: '/find',
templateUrl: 'views/find.html',
controller: 'findCtrl'
})
.state('index', {
url: '/index',
templateUrl: 'views/index.html',
controller: 'CarouselDemoCtrl'
})
}]);
This is the index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Discover It!</title>
<script src = "https://plus.google.com/js/client:platform.js" async defer></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container" ng-app="app">
<div ng-controller="CarouselDemoCtrl">
<div style="height: 305px">
<div uib-carousel active="active" interval="myInterval" no-wrap="noWrapSlides">
<div uib-slide ng-repeat="slide in slides track by slide.id" index="slide.id">
<img ng-src="{{slide.image}}" style="margin:auto;">
<div class="carousel-caption">
<h4>Name: {{slide.name}}</h4>
<p>{{slide.description}}</p>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-2.2.3.js" integrity="sha256-laXWtGydpwqJ8JA+X9x2miwmaiKhn8tVmOVEigRNtP4=" crossorigin="anonymous"></script>
<script src="//widget.cloudinary.com/global/all.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.1/angular-ui-router.js"></script>
<script src="scripts/angular-animate/angular-animate.min.js"></script>
<script src="scripts/angular-ui-bootstrap/dist/ui-bootstrap-tpls.js"></script>
<script src="scripts/app.js"></script>
<script src="scripts/controllers/profileCtrl.js"></script>
<script src="scripts/controllers/discoverCtrl.js"></script>
<script src="scripts/controllers/findCtrl.js"></script>
<script src="scripts/controllers/indexCtrl.js"></script>
I have updated to add where my code currently is and more information since maybe my issue is coming from a different area.
The problem was that I had errors in my for loop logic trying to access information that was undefined, which somehow caused the "Argument 'CarouselDemoCtrl' is not a function, got undefined" error." So if you get an error like this complaining about the controller, try to check your logic too.

Angular - ngOptions model value not updating

Getting started with Angular and am having an issue getting the model binding to work for a select option in a template.
I have the following ng-options select in a template:
<select ng-model="listenercount" ng-options="n for n in [] | range:0:1000" ng-change="listenersUpdate()"></select>
I have filter which looks like this:
angular.module('myapp').filter('range', function() {
return function(input, min, max) {
min = parseInt(min);
max = parseInt(max);
for (var i=min; i<max; i++) {
input.push(i);
}
return input;
};
});
My select shows up correctly with options 0-1000 based on my filter.
In my controller I have the following:
$scope.listenercount = 0;
$scope.listenersUpdate = function() {
alert('new listener count is now:' + $scope.listenercount);
}
My alert message pops up every time I change the select as expected, but it always show $scope.listenercount = 0. The $scope.listenercount model binding does not seem to be update the value.
Anything obvious I am doing wrong?
<body ng-app="myapp">
<script>
angular.module('myapp', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.listenercount = 0;
$scope.listenersUpdate = function() {
alert('new listener count is now:' + $scope.listenercount);
}
}]);
angular.module('myapp').filter('range', function() {
return function(input, min, max) {
min = parseInt(min);
max = parseInt(max);
for (var i=min; i<max; i++) {
input.push(i);
}
return input;
};
});
</script>
<div ng-controller="ExampleController">
<select ng-model="listenercount" ng-options="n for n in [] | range:0:1000" ng-change="listenersUpdate()"></select>
<tt>debug = {{confirmed}}</tt><br/>
<tt>counter = {{counter}}</tt><br/>
</div>
</body>
This is working as expected

Angular Js and Partition

I want to show the data in the form of row and column . I am having list of data in the form of array . I am using onsenui
Here is the code
<link rel="stylesheet" href="lib/onsen/css/onsenui.css">
<link rel="stylesheet" href="lib/onsen/css/onsen-css-components.css">
<script src="lib/onsen/js/angular/angular.js"></script>
<script src="lib/onsen/js/onsenui.js"></script>
<script>
ons.bootstrap();
function MyCtrl($scope)
{
$scope.inside ="asd";
$scope.names = [
{name:'Mac',path:'http://www.hdicon.com/wp-content/uploads/2010/07/McDonalds_golden_arch.png'},
{name:'KFC',path:'http://facebookazine.com/wp-content/uploads/2012/06/KFC_icon.jpg'},
{name:'Karlsruhe',path:'http://media-cache-ak0.pinimg.com/736x/8b/55/44/8b55442ccb4d3f3ac514a1dceaa3ea43.jpg'}
];
}
</script>
Here is the html code
<div ng-controller="MyCtrl" >
<ons-row ng-repeat ="x in names| partition:2" class="center">
<ons-col>
<img src ="{{x.path}}" width="100px"/>
</ons-col>
<ons-col>
<h4>{{x.name}}</h4>
</ons-col>
</ons-row>
</div>
When i open the page i am getting this error
Error: [$injector:unpr] Unknown provider: partitionFilterProvider <- partitionFilter
http://errors.angularjs.org/1.2.10/$injector/unpr?p0=partitionFilterProvider%20%3C-%20partitionFilter
I searched this error on Internet but i didnt get any solution to this
Check below code (Filter partition code is implemented in my project which was taken from blog)
var app = angular.module('MyApp', [])
.controller('MyCtrl', function ($scope) {
$scope.inside ="asd";
$scope.names = [
{name:'Mac',path:'http://www.hdicon.com/wp-content/uploads/2010/07/McDonalds_golden_arch.png'},
{name:'KFC',path:'http://facebookazine.com/wp-content/uploads/2012/06/KFC_icon.jpg'},
{name:'Karlsruhe',path:'http://media-cache- ak0.pinimg.com/736x/8b/55/44/8b55442ccb4d3f3ac514a1dceaa3ea43.jpg'}
];
}
.filter('partition', function () {
var cache = {};
var filter = function (arr, size) {
if (!arr) { return; }
var newArr = [];
for (var i = 0; i < arr.length; i += size) {
newArr.push(arr.slice(i, i + size));
}
var arrString = JSON.stringify(arr);
var fromCache = cache[arrString + size];
if (JSON.stringify(fromCache) === JSON.stringify(newArr)) {
return fromCache;
}
cache[arrString + size] = newArr;
return newArr;
};
return filter;
})

AngularJs. Cycle in $scope.$watch

I can't understand whats wrong. I need create array of hours and minutes and show him.
HTML:
<div ng-app="test">
<div ng-controller="timeCtrl" ng-init="opentime='9';closetime='24'">
<div ng-repeat="time in times">
{{time}}
</div>
</div>
</div>
JS:
var app = angular.module('test', []);
app.controller('timeCtrl', ['$scope', function ($scope) {
$scope.$watch('opentime', function () {
$scope.times = [];
for (var hours = $scope.opentime; hours < $scope.closetime; hours++) {
console.log(hours);
for (var minutes = 0; minutes < 4; minutes++) {
var linkMinutes = minutes * 15;
if (linkMinutes === 0) {
linkMinutes = "00";
}
console.log(linkMinutes);
$scope.times.push(hours + ':' + linkMinutes);
}
}
});
}])
Why console.log is empty, but vars opentime and closetime with value?
Fiddle: http://jsfiddle.net/Zoomer/mj8zv2qL/
that because your scope variable opentime never been changed to fire watcher
I'v updated the example and simulated the variable change
scope.$watch will execute only when opentime change value please see more here https://docs.angularjs.org/api/ng/type/$rootScope.Scope
and that demo http://jsfiddle.net/oprhy6te/enter link description here
CTRL:
app.controller('timeCtrl', ['$scope', function ($scope) {
$scope.$watch('opentime', function () {
$scope.updateTimes();
});
$scope.updateTimes = function () {
$scope.times = [];
for (var hours = $scope.opentime; hours < $scope.closetime; hours++) {
console.log(hours);
for (var minutes = 0; minutes < 4; minutes++) {
var linkMinutes = minutes * 15;
if (linkMinutes === 0) {
linkMinutes = "00";
}
console.log(linkMinutes);
$scope.times.push(hours + ':' + linkMinutes);
}
}
}
function activate() {
$scope.opentime = 9;
$scope.closetime = 13;
$scope.updateTimes();
}
activate();
}])
HTML:
<div ng-app="test">
<div ng-controller="timeCtrl">
<input type="text" ng-model="opentime" />
<div ng-repeat="time in times"> {{time}}
</div>
</div>
</div>

Resources