How to pass AngularJS expressions to controller - javascript

I want to pass AngularJS Expression value to the controller.
HTML code :
<div data-ng-controller="AlbumCtrl">
<div data-ng-repeat="z in songInfo">
<div data-ng-repeat="b in z.album">
{{b.tracks}}
</div>
</div>
<!-- Pagination -->
<div class="pageing">
<a class="prev" data-ng-disabled="currentPage == 0" data-ng-click="currentPage=currentPage-1">prev</a>
<a class="pageingg" href="#/song">{{currentPage+1}}/{{numberOfPages()}}</a>
<a class="next" data-ng-disabled="currentPage >= data.length/pageSize - 1" data-ng-click="currentPage=currentPage+1">next</a>
</div>
</div>
Here {{b.tracks}} is the count of total number of tracks in the album. I have to pass this data to the controller AlbumCtrl.
Controller :
.controller('AlbumCtrl', function($scope, $routeParams, $http) {
$scope.album_id = $routeParams.albumId;
$http.post('api-call.php', { albumid: $scope.album_id, evt: 13 }).success(function(data) {
$scope.songInfo = data;
});
//Pagination
$scope.currentPage = 0;
$scope.pageSize = 10;
$scope.data = [];
$scope.numberOfPages=function(){
return Math.ceil($scope.data.length/$scope.pageSize);
};
for (var i=0; i<AngularJS expression value; i++) {
$scope.data.push("Item "+i);
}
});
Here, in controller AngularJS expression value is the value we have to get here.

if it have only one value. then you can easily get the values from controller, you don't need to pass it.
try this way $scope.songInfo[0].album[0].tracks
Something like
for (var i=0; i< $scope.songInfo[0].album[0].tracks; i++) {
$scope.data.push("Item "+i);
}

Try this two line,
var obj = JSON.parse($scope.songInfo);
var track = obj.root.tracks[0];

Related

Angular Nested Controller in ng-repeat

I'm trying to use a nested controller in an ng-repeat so that the accordion panels on the page operate in different scopes (there may be a better way to do this). The problem is that the code in the nested controller never gets executed. I put a "debugger" stop point at the top and it never gets hit.
Here is my HTML:
<script src="~/Scripts/app/LWS/LWSCtrl.js"></script>
<script src="~/Scripts/app/LWS/lwsService.js"></script>
<script src="~/Scripts/app/Common/commonCtrl.js"></script>
<script src="~/Scripts/app/Common/commonService.js"></script>
<div ng-app-="myModule" ng-controller="LWSCtrl">
<div cg-busy="waitopr"></div>
<tabset>
<tab heading="Dashboard">
<div ng-repeat="m in majors">
<div ng-controller="commonCtrl">
<accordion close-others="oneAtATime">
<accordion-group is-open="status.open">
<accordion-heading>
<div style="height:20px">
<span class="pull-left">{{m.MajorName}}</span><i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-up': status.open, 'glyphicon-chevron-down': !status.open}"></i>
</div>
</accordion-heading>
...(shortened for brevity)
Here is the nested controller in its entirety:
angular.module('myModule').controller('commonCtrl', function ($scope, commonService, $, $timeout, $filter, $interval, $window) {
debugger;
$scope.oneAtATime = true;
$scope.status = {
isFirstOpen: false,
isFirstDisabled: false
};
getDashboard();
function getDashboard() {
$scope.waitopr = commonService.getlwsdashboard()
.success(function (data) {
$scope.dashboard = data;
var arr = {};
for (var i = 0, len = $scope.dashboard.length; i < len; i++) {
arr[$scope.dashboard[i]['CompanyID']] = $scope.dashboard[i];
};
$scope.majors = new Array();
for (var key in arr) {
$scope.majors.push(arr[key]);
}
angular.forEach($scope.majors, function (value, key) {
for (var i = 0; i < $scope.dashboard.length; i++) {
if (value.CompanyID == $scope.dashboard[i].CompanyID) {
$scope.majors[key].header = $scope.dashboard[i];
};
}
})
angular.forEach($scope.majors, function (value, key) {
$scope.waitopr = commonService.getlegend(value.CompanyID)
.success(function (data) {
$scope.majors[key].Legend = data;
for (var i = 0; i < $scope.dashboard.length; i++) {
if (value.CompanyID == $scope.dashboard[i].CompanyID) {
$scope.majors[key].MajorName = $scope.dashboard[i].MajorName;
};
}
});//end success
});//end forEach
angular.forEach($scope.majors, function (value, key) {
for (var i = 0; i < $scope.dashboard.length; i++) {
if (value.CompanyID == $scope.dashboard[i].CompanyID) {
items.push($scope.dashboard[i]);
};
}
$scope.majors[key].items = items;
items = [];
})
});//end success
};
})
I don't understand why the nested controller code is not executing. Any assistance is greatly appreciated!
Your controller is attached to an element within an ng-repeat. If the item you're repeating on is empty/undefined, your controller instance will never be invoked.
You must ensure that majors is populated and non-empty in the parent $scope.

how to pass value to directive as a parameter of ng-init

i was trying to pass the list of value when page is loaded. but my ng-init function not even getting trigger. whats the problem with my code.
<li class="tag" ng-repeat="list in displayItems track by $index" ng-class="{selected: $index==selectedIndex}" data-ng-init="display(selecteditemslist,searchid)">
<span class="tag-label">{{list}}</span><span class="tag-cross pointer" ng-click="Delete($index,selecteditemslist[$index],list,searchid)">x</span>
</li>
to the function in controller
$scope.display=function(list,searchid){
console.clear();
console.info(list);
console.info(searchid);
switch(searchid) {
case 'organisation' :
for(var i=0; i<list.length; i++){
getOrg(list[i]).fetch({}).$promise.then(
function (value) {
$scope.displayItem = value.data[0];
console.clear();
console.info($scope.displayItem);
$scope.displayItems.push($scope.displayItem.displayConfig[0].propertyValue);
//$scope.displayItems = $scope.displayItem.displayConfig[0].propertyValue;
console.info($scope.displayItems);
});
}
break;
case 'people' :
for(var j=0; j<list.length; j++) {
getPeople(list[j]).fetch({}).$promise.then(
function (value) {
$scope.displayItem = value.data[0];
console.info($scope.displayItem);
$scope.displayItems.push($scope.displayItem.displayConfig[0].propertyValue);
//$scope.displayItems = $scope.displayItem.displayConfig[0].propertyValue;
console.info($scope.displayItem.displayConfig[0].propertyValue);
console.info($scope.displayItems);
});
}
break;
}
}
Short answer:
<ul data-ng-init="display(selecteditemslist,searchid)">
<li class="tag" ng-repeat="list in displayItems track by $index" ng-class="{selected: $index==selectedIndex}">
<span class="tag-label">{{list}}</span><span class="tag-cross pointer" ng-click="Delete($index,selecteditemslist[$index],list,searchid)">x</span>
</li>
</ul>
Long Answer:
Let’s see how the directive ng-repeat works.
First of all:
var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
var NG_REMOVED = '$$NG_REMOVED';
var ngRepeatMinErr = minErr('ngRepeat');
...
return {
restrict: 'A',
multiElement: true,
transclude: 'element',
priority: 1000,
terminal: true,
$$tlb: true,
compile: function ngRepeatCompile($element, $attr) {
var expression = $attr.ngRepeat;
...
var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
var lhs = match[1];
var rhs = match[2]; <--- in this case `displayItems`
var aliasAs = match[3];
var trackByExp = match[4];
After that $scope.$watchCollection(rhs, function ngRepeatAction(collection) { ... }) is being made in ngRepeatLink.
As a result if displayItems is empty, we will get html comment: <!-- ngRepeat: list in displayItems --> instead of what you probably supposed to see: <div ng-repeat="list in displayItems" ng-init="display(selecteditemslist,searchid)">.
That’s why ng-init doesn’t initialize :)

AngularJS directive templates ng-repeat funny substitution

I'm struggling with angularjs directive templates. The {{variable}} works in a very strange way inside a ng-repeat,
<div ng-controller="MyCtrl">
<h2>here i am</h2>
<button type="button" ng-click="addItem()" class="btn btn-primary">Howdy</button>
<div ng-repeat="item in items track by $index" itemlist></div>
</div>
<script type="text/ng-template" id="template.html">
<div>
Howdy {{item.itemNum}} {{item.name}}
</div>
</script>
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function ($scope) {
$scope.count = 0;
$scope.items = [];
var newItem = {
itemNum: 0,
name: "New"
};
$scope.addItem = function () {
newItem.itemNum = $scope.count;
console.log('adding item ' + newItem.itemNum);
$scope.items.push(newItem);
$scope.count += 1;
};
});
myApp.directive('itemlist', function ($compile) {
return {
templateUrl: 'template.html',
};
});
I have created a jsfiddle showing my problem here: http://jsfiddle.net/dk253/8jm5tjvf/23/.
What am I missing or doing wrong?
Thanks!
The reason is you are updating the property on the same object reference (newItem) every time. So it updates all other items in the array because they all just point to the same object or in other words they are all same. You could instead get the copy of the object using angular.copy and push that item.
var item = {
itemNum: 0,
name: "New"
};
$scope.addItem = function () {
var newItem = angular.copy(item); //Get the copy
newItem.itemNum = $scope.count;
Fiddle

Angular js function logic and repetition error

I'm having a logic error with my code using angular js. What I have done is made a function that loops through a json array and returns the strings of the weather condition, eg
'clear',
'cloudy', etc...
It then checks to see if the value of the string is equal to another string. If it is, it returns an image link associated with the weather condition. The problem is that html ng-repeat function is repeating that one image and not any other image.
Here is the js:
var app=angular.module('app');
app.controller('MainCtrl', function($scope, $http) {
$scope.currentSydney = null;
$scope.currentMelbourne = null;
$scope.currentAdelaide = null;
$scope.currentDarwin = null;
$scope.currentBrisbane = null;
$scope.currentMelbourne = null;
$scope.currentCairns = null;
$http.jsonp('http://api.wunderground.com/api/5ad0204df4bdbeff/conditions/q/Australia/Melbourne.json?callback=JSON_CALLBACK').success(function(data){
$scope.currentMelbourne=data;
});
$http.jsonp('http://api.wunderground.com/api/5ad0204df4bdbeff/conditions/q/Australia/Sydney.json?callback=JSON_CALLBACK').success(function(data){
$scope.currentSydney=data;
});
$http.jsonp('http://api.wunderground.com/api/5ad0204df4bdbeff/conditions/q/Australia/Adelaide.json?callback=JSON_CALLBACK').success(function(data){
$scope.currentAdelaide=data;
});
$http.jsonp('http://api.wunderground.com/api/5ad0204df4bdbeff/conditions/q/Australia/Darwin.json?callback=JSON_CALLBACK').success(function(data){
$scope.currentDarwin=data;
});
$http.jsonp('http://api.wunderground.com/api/5ad0204df4bdbeff/conditions/q/Australia/Perth.json?callback=JSON_CALLBACK').success(function(data){
$scope.currentPerth=data;
});
$http.jsonp('http://api.wunderground.com/api/5ad0204df4bdbeff/conditions/q/Australia/Cairns.json?callback=JSON_CALLBACK').success(function(data){
$scope.currentCairns=data;
});
$http.jsonp('http://api.wunderground.com/api/5ad0204df4bdbeff/conditions/q/Australia/Brisbane.json?callback=JSON_CALLBACK').success(function(data){
$scope.currentBrisbane=data;
$scope.cityData=[
{ name:'Brisbane',
temp:$scope.currentBrisbane.current_observation.temp_c,
image:$scope.currentBrisbane.current_observation.icon
},
{ name:'Melbourne',
temp:$scope.currentMelbourne.current_observation.temp_c,
image:$scope.currentMelbourne.current_observation.icon
},
{
name:'Adelaide',
temp:$scope.currentAdelaide.current_observation.temp_c ,
image:$scope.currentAdelaide.current_observation.icon
},
{ name:'Darwin',
temp:$scope.currentDarwin.current_observation.temp_c ,
image:$scope.currentDarwin.current_observation.icon
},
{ name:'Perth',
temp:$scope.currentPerth.current_observation.temp_c ,
image:$scope.currentPerth.current_observation.icon
},
{ name:'Cairns',
temp:$scope.currentCairns.current_observation.temp_c,
image:$scope.currentCairns.current_observation.icon
},
]
for(y = 0 ; y < 6; y++){
var string = $scope.cityData[y].image;
console.log(string[10]);
}
});
$scope.iconString = function() {
switch ($scope.currentSydney.current_observation.icon) {
case 'partlycloudy' :
return 'pics/partlycloudy.png';
case 'clear' :
return 'pics/partlycloudy.png';
}
}
$scope.repeat = function() {
for(y = 0 ; y < 1; y++){
var string = $scope.cityData[y].image;
if(string=='mostlycloudy'){
return 'pics/mostlycloudy.png';
}
}
}
});
And here is the html:
<div id="weather-container">
<div id="current-weather">
<!--Angular JSON pull -->
<div id="title"><span id="current-title">Current Weather</span></div>
<div id="current-condition">{{currentSydney.current_observation.weather}}</div>
<img ng-src="{{iconString()}}"></img>
<div id="current-temp"><span id="current-temp"> {{currentSydney.current_observation.temp_c}} </span></div>
<span id="current-city">{{currentSydney.current_observation.display_location.city}} </span>
</div>
<!--Angular JSON pull and iteration-->
<div id="other-city-container">
<div class="other-city-weather" ng-repeat="city in cityData" >
<!--Image-->
<img ng-src="{{repeat()}}"></img>
<div class="current-city-temp">
<span>{{city.temp}}</span>
</div>
<div class="current-city-lower">
<span>{{city.name}}</span>
</div>
</div>
</div>
</div>
Now I'm calling the repeat function in the html inside the img src tag.
`
I see. You are making 2 loops : ng-repeat in the view, and a for loop in the controller ( repeat() ).
But I think that right now, they are not related to each other (which is what you need I guess): getting the index of the ng-repeat loop in your repeat method.
Try something like that :
In the view :
<img ng-src="{{repeat($index)}}" /><!-- Getting the current $index of the ng-repeat loop and passing it to the $scope.repeat() method -->
In the controller :
$scope.repeat = function(index) { // there, index becomes the value we just put in the view ($index = the current index of the ng-repeat loop), e.g. : 0,1,2,3...
var string = $scope.cityData[index].image; // We go get the right city in the cityData array, according to the current ng-repeat index.
// then we do the job
if(string=='mostlycloudy'){
return 'pics/mostlycloudy.png';
}
}
Not sure that works as I didn't test it, but you may know what I mean ?

$scope not filtering with other parts of controller in AngularJS

I have a controller that is pretty much an exact copy of the demo from AngularJS. I wanted to add a function to grab some items from an array within the items.
The issue I am running into is that the results are not filtering along with the main part of the controller.
Here is the original part of the controller.
function EmployerListCtrl($scope, Employer) {
$scope.employers = Employer.query();
$scope.orderProp = 'age';
$scope.getEmployerCount = function () {
return $scope.employers.length;
};
I added this function.
$scope.getSkillsList = function () {
var employerArray = this.employers;
var skillsArray = new Array();
for (var i = 0; i < employerArray.length; i++) {
if (employerArray[i].software != undefined || employerArray[i].software != null) {
for (var j = 0; j < employerArray[i].software.length; j++) {
skillsArray.push(employerArray[i].software[j]);
}
}
}
return skillsArray;
};
I also tried to use the same $scope as the main part of the controller, however it also shows just the initial results.
$scope.getSkillsList2 = function () {
var employerArray = $scope.employers;
var skillsArray = new Array();
for (var i = 0; i < employerArray.length; i++) {
if (employerArray[i].software != undefined || employerArray[i].software != null) {
for (var j = 0; j < employerArray[i].software.length; j++) {
skillsArray.push(employerArray[i].software[j]);
}
}
}
return skillsArray;
};
Here is the contents of the HTML Page. The ng-model="query" is what I am using to filter the ng-repeat.
<div class="container-fluid">
<p>Set One: {{getSkillsList()}}</p>
<p>Set Two: {{getSkillsList2()}}</p>
<div class="row-fluid">
<div class="span2">
<!--Sidebar content-->
Search: <input ng-model="query">
Sort by:
<select ng-model="orderProp">
<option value="name">Alphabetical</option>
<option value="age">Newest</option>
</select>
<p>Number of employers in list: {{getEmployerCount()}}</p>
</div>
<div class="span10">
<!--Body content-->
<ul class="employers">
<li ng-repeat="employer in employers | filter:query | orderBy:orderProp" class="thumbnail">
<img ng-src="{{employer.imageUrl}}">
{{employer.name}}
<p>{{employer.snippet}}</p>
</li>
</ul>
</div>
</div>
</div>
I think you are hoping to have the skillsArray automatically shrink or grow based on the ng-repeat filter. That won't work. In this line:
<li ng-repeat="employer in employers | filter:query | orderBy:orderProp" ...>
the results of the filter are not seen by the parent scope, but only by the ng-repeat scopes. In other words, the filter does not alter $scope.employers, so your skills functions will continue to operate on the full employers array received from the server.
One way to accomplish what you want is to define your own filter function, then chain it with the query filter one:
angular.module('myApp', []).
filter('skills', function() {
return function(filteredEmployers) {
var skillsArray = [];
... do your filtering here ...
return skillsArray;
}
});
Then in your HTML:
<li ng-repeat="skills in employers | filter:query | skills">
{{skill}}
</li>
See also Creating Angular Filters.

Categories

Resources