Argument 'CarouselDemoCtrl' is not a function, got undefined - angularjs

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.

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>

Angular ui-grid use selectedrow feature to control content of a row column

I would like to the ui-grid row select feature to set the value of a column in the clicked row.
I have a column in the DB named omit. I would like that value to equal the state of the selected row, so if the row is selected then omit = 1, if row is not selected then omit = 0. I think I have this part figured out (however I'm always open to better ideas!).
gridApi.selection.on.rowSelectionChanged($scope,function(row){
if(row.isSelected){
row.entity.omit = 1;
}
if(!row.isSelected){
row.entity.omit = 0;
}
// now save to database...
});
gridApi.selection.on.rowSelectionChangedBatch($scope,function(rows){
angular.forEach(rows, function(value, key) {
if(value.isSelected){
value.entity.omit = 1;
}
if(!value.isSelected){
value.entity.omit = 0;
}
// now save to database...
});
});
What I haven't been able to figure out is how the select the row when the grid is first loaded.
So, on the initial load of the grid, how do I select the row if the value of omit is 1?
You can use the gridApi.selection.selectRow method, but you have to wait until the grid has digested the data for it to work. So you either have to set it on an $interval (or after a $timeout) to keep running while the grid digests the data, or you can call gridApi.grid.modifyRows($scope.gridOptions.data) before you call selectRow... to be honest, I'm not sure why you have to call that.
var app = angular.module('app', ['ngTouch', 'ui.grid', 'ui.grid.selection']);
app.controller('gridCtrl', ['$scope', '$http', '$interval', 'uiGridConstants', function ($scope, $http, $interval, uiGridConstants) {
$scope.gridOptions = { enableRowSelection: true, enableRowHeaderSelection: false };
$scope.gridOptions.columnDefs = [
{ name: 'omit' },
{ name: 'id' },
{ name: 'name'},
{ name: 'age', displayName: 'Age (not focusable)', allowCellFocus : false },
{ name: 'address.city' }
];
$scope.gridOptions.multiSelect = false;
$scope.gridOptions.modifierKeysToMultiSelect = false;
$scope.gridOptions.noUnselect = true;
$scope.gridOptions.onRegisterApi = function( gridApi ) {
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope,function(row){
if(row.isSelected){
row.entity.omit = 1;
}
if(!row.isSelected){
row.entity.omit = 0;
}
// now save to database...
});
gridApi.selection.on.rowSelectionChangedBatch($scope,function(rows){
angular.forEach(rows, function(value, key) {
if(value.isSelected){
value.entity.omit = 1;
}
if(!value.isSelected){
value.entity.omit = 0;
}
// now save to database...
});
});
};
$scope.toggleRowSelection = function() {
$scope.gridApi.selection.clearSelectedRows();
$scope.gridOptions.enableRowSelection = !$scope.gridOptions.enableRowSelection;
$scope.gridApi.core.notifyDataChange( uiGridConstants.dataChange.OPTIONS);
};
$http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/500_complex.json')
.success(function(data) {
_.forEach(data, function(row) {
row.omit = 0;
});
/* arbitrarily setting the fourth row's omit value to 1*/
data[3].omit = 1;
$scope.gridOptions.data = data;
/* using lodash find method to grab the row with omit === 1 */
/* could also use native JS filter, which returns array rather than object */
var initSelected = _.find($scope.gridOptions.data, function(row) { return row.omit === 1; });
$scope.gridApi.grid.modifyRows($scope.gridOptions.data);
$scope.gridApi.selection.selectRow(initSelected);
/**
* OR:
* $interval( function() {
* $scope.gridApi.selection.selectRow(initSelected);
* }, 0, 1);
*/
});
}]);
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="lodash.js#4.6.1" data-semver="4.6.1" src="https://cdn.jsdelivr.net/lodash/4.6.1/lodash.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-touch.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/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="gridCtrl">
<div ui-grid="gridOptions" ui-grid-selection="" class="grid"></div>
</div>
</body>
</html>

Pulled out all my hair on an Angular unpr error

So I am getting an angular [$injector:unpr] error. Yes, I know what that normally means...I haven't defined something somewhere, or I am redefining the module over and over, or the like...but for the life of me I'm struggling to see the issue in my code.
I'm sure I'm missing something insanely basic, but after I've stared at code for a couple of hours, I go blind to it.
My HTML File:
<!DOCTYPE html>
<html ng-app="email">
<head>
<meta charset="UTF-8">
<title>Authentication</title>
<link href='https://fonts.googleapis.com/css?family=Roboto:400,100,300,500,700' rel='stylesheet' type='text/css'/>
<meta content="width=device-width, initial-scale=1.0" name="viewport">
</head>
<body>
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="node_modules/angular/angular.min.js"></script>
<div ng-controller="EmailAuthController as auth">
<h1>Authentication</h1>
<p>Request: [{{auth.request}}]</p>
<p>{{auth.response}}</p>
<p>{{1+2}}</p>
</div>
<script type="text/javascript" src="js/controllers/email.js"></script>
</body>
</html>
My email.js file (As you can see, I've commented out some stuff to try to isolate the issue):
/* global angular parseGet */
function parseGet(val) {
var result = '', // = "Not found",
tmp = [];
var items = location.search.substr(1).split('&');
for (var index = 0; index < items.length; index++) {
tmp = items[index].split('=');
if (tmp[0] === val) {
result = decodeURIComponent(tmp[1]);
}
}
return result;
}
(function () {
angular
.module('email', [])
.controller('EmailAuthController', [ '$scope','authFactory', function ($scope,authFactory) {
var vm = this,
req = parseGet('hash') || '';
vm.request = req;
// authFactory.validate(req)
// .then(function (response) {
// vm.response = response.data;
// });
}])
.factory('authFactory', [ '$rootScope', '$http', 'config', function ($rootScope, $http, config) {
var validate = function (hash) {
var url = config.SERVICE_URI + '/auth/email/' + hash;
return $http.get(url);
};
return {
validate: validate
};
}]);
})();
From the code you've given it appears config is not defined in your authFactory injection.
.factory('authFactory', [ '$rootScope', '$http', 'config', function(a, b, c) {} ]); // config is not defined

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;
})

How does service variable change update to controllers

I have a small problem and I don't understand this thing:
When I add an item to TestiFactorys arr - array it does update to both controllers
On the other hand why does not TestiFactorys arr_len update to both controllers. And in TestiController why do I have to "manually" update TestControllers list1_length to make it update to view but I don't have to update TestiContollers list1 to make it update to view
I am assuming that my poor Javascript or Javascript variable scope understanding is causing this but i just don't see it.
I am using AngularJS version 1.2.16
<!DOCTYPE html>
<html ng-app="TestiApp">
<head>
<title></title>
</head>
<body>
<div ng-controller="TestController">
List items from controller: {{list1}}<br>
List item count:{{list1_length}}
<input type="text" ng-model="param"><br>
<button ng-click="list1_add(param)">asd</button>
</div>
<br><br>
<div ng-controller="TestController2">
List items from controller2{{list2}} <br>
List items count in from controller2: {{list2_length}}
</div>
<script src="scripts/angular.min.js"></script>
<script src="scripts/app.js"></script>
</body>
</html>
And this is my app.js:
var TestiApp = angular.module('TestiApp', [])
TestiApp.factory('TestiFactory',function() {
var arr = ['abx','cbs'];
var arr_len = arr.length;
return {
list : function() {
return arr;
},
add_to_arr : function(n) {
arr.push(n);
},
arr_len : function() {
arr_len = arr.length;
return arr_len;
}
}
}
);
TestiApp.controller('TestController', function($scope, TestiFactory) {
$scope.list1 = TestiFactory.list();
$scope.list1_length = TestiFactory.arr_len();
$scope.list1_add = function (d) {
TestiFactory.add_to_arr(d);
$scope.param = '';
$scope.list1_length = TestiFactory.arr_len();
}
});
TestiApp.controller('TestController2', function($scope, TestiFactory) {
$scope.list2 = TestiFactory.list();
$scope.list2_length = TestiFactory.arr_len();
});
EDIT WITH SOLUTION
Here is working solution. Based to comments I decided to do more studying on Javascripts basics which
is of course the thing I should have done before trying to use this complex framework which uses Javascript. So now I have some basic understanding how to use references in Javascript and what primitive data types are. And based on that here is working version:
<!DOCTYPE html>
<html ng-app="TestiApp">
<head>
<title></title>
</head>
<body>
<div ng-controller="TestController">
List items from controller: {{list1()}}<br>
List item count:{{list1_len()}}
<input type="text" ng-model="param"><br>
<button ng-click="list1_add(param)">asd</button>
</div>
<br><br>
<div ng-controller="TestController2">
List items from controller2{{list2()}} <br>
List items count in from controller2: {{list2_length()}}
</div>
<script src="scripts/angular.min.js"></script>
<script src="scripts/app.js"></script>
</body>
</html>
And app.js:
var TestiApp = angular.module('TestiApp', [])
TestiApp.factory('TestiFactory',function() {
var arr = ['abx','cbs'];
return {
list : function() {
return arr;
},
add_to_arr : function(n) {
arr.push(n);
},
arr_len : function() {
return arr.length;
}
}
}
);
TestiApp.controller('TestController', function($scope, TestiFactory) {
$scope.list1 = TestiFactory.list;
$scope.list1_add = TestiFactory.add_to_arr;
$scope.list1_len = TestiFactory.arr_len;
});
TestiApp.controller('TestController2', function($scope, TestiFactory) {
$scope.list2 = TestiFactory.list;
$scope.list2_length = TestiFactory.arr_len;
});
I've ran into this many times. Factories and services in angular are not like scopes...they work using references. The reason the array updates in your controllers is because the original reference was updated. The length is not updating because the number type is primitive.
This should work:
TestiApp.controller('TestController', function($scope, TestiFactory) {
$scope.list1 = TestiFactory.list();
$scope.$watch('list1', function(list1) {
$scope.list1_length = list1.length;
});
$scope.list1_add = function (d) {
TestiFactory.add_to_arr(d);
$scope.param = '';
};
});
TestiApp.controller('TestController2', function($scope, TestiFactory) {
$scope.list2 = TestiFactory.list();
$scope.$watch('list2', function(list2) {
$scope.list2_length = list2.length;
});
});

Resources