How to concat 2 expressions in interpolate - angularjs

I have directive where I want to render a list from various objects.
Controller:
$scope.propertyName = 'price';
View:
<div ng-repeat="item in obj">
<a>{{ 'item.' + propertyName }}</a>
</div>
Objects obj will have various properties and I can't use static property name.
{{ 'item.' + propertyName }} return string 'item.price' - I want expression like {{ item.price }}.

Just like you would do in JavaScript:
{{ item[propertyName] }}

Related

Issue with Ngfor only supports binding to Iterables such as Arrays

error
supporting object 'Active' of type 'string'. NgFor only supports binding to Iterables such as Arrays.
I was trying to make it where every time i click the toggle it will change the {{ setting }} from Inactive to active. was trying to get this method working if the other one fails to be possible.
code html:
<ion-item>
<ion-label>Front Door</ion-label>
<ion-toggle [(ngModel)]="fdoor" ng-model="ni_toggle" (ionChange)="Fdoor()" (click)="change()"></ion-toggle>
</ion-item>
<div *ngFor="let setting of sett">
{{ setting }}
</div>
ts:
active: string = "Active"
inactive: string = "Inactive"
change() {
if(this.fdoor = true) {
this.sett = this.active
}
}
I don't know what is your purpose. But I think you should do like this:
sett = false;
change() {
if(this.fdoor = true) {
this.sett = !this.sett;
}
}
HTML
<ion-item>
<ion-label>Front Door</ion-label>
<ion-toggle [(ngModel)]="fdoor" ng-model="ni_toggle" (ionChange)="Fdoor()" (click)="change()"></ion-toggle>
</ion-item>
<div>
{{ sett ? "Active" : "Inactive" }}
</div>

Angular expression in ng-repeat and ng-click

I am trying to call a function using ng-click which is dynamically generated by ng-repeat the problem is that i am not able to get the parameter value passed in ng-click function. My html code is
<div class="col-md-4 col-xs-12 col-lg-4" ng-repeat="(key, value) in uploadedFiles">
<b>value.filename is {{value.filename}}</b>
<img ng-if="value.filetype=='jpg'" ng-src="http://localhost:3000/uploads/{{value.filename}}" class="img img-responsive thumbnail uploadedfile-thumb"/>
<img ng-if="value.filetype=='PDF'" ng-src="images/pdf-thumb.jpg" class="img img-responsive thumbnail uploadedfile-thumb"/>
<a ng-href="http://localhost:3000/uploads/{{value.filename}}" target="_blank" class="uploaded-file-links">View</a>
<a ng-href="#" ng-click="deleteFile(value.filename);" class="uploaded-file-links">Delete</a>
</div>
i am not getting the filename which is passed in deleteFile(), bit it is working in <b> tag in 2nd line so finally this is a problem with my angular expression so how should i write it?
I will try to make some guessing here.
I suppose that your uploadedFiles is an array of objecs, and not an object itself. In that case, you should use ng-repeat="file in uploadedFiles" which is meant to iterate over array elements. This will iterate over your array and assignf the corresponding object for that iteration to file variable.
The ng-repeat="(key, value) in uploadedFiles" is meant for iterating over object properties instead of iterating over array elements. For example, if uploadedFiles is:
var uploadedFiles = {
prop1: 'value1',
prop2: 'value2',
prop3: 'value3'
};
and you iterate over it like this:
<ul>
<li ng-repeat="(key, value) in uploadedFiles">
{{value}}
</li>
</ul>
you would get the following output:
value1
value2
value3
But if uploadedFiles is an array like this one:
var uploadedFiles = [
{
prop1: 'value11',
prop2: 'value12',
},
{
prop1: 'value21',
prop2: 'value22',
},
{
prop1: 'value31',
prop2: 'value32',
}
];
And you iterate over it like this:
<ul>
<li ng-repeat="file in uploadedFiles">
{{file.prop1}}
</li>
</ul>
you would get:
value11
value21
value31
So in your case, I would try the following:
<div class="col-md-4 col-xs-12 col-lg-4" ng-repeat="file in uploadedFiles">
<b>file.filename is {{file.filename}}</b>
<img ng-if="file.filetype=='jpg'" ng-src="http://localhost:3000/uploads/{{file.filename}}" class="img img-responsive thumbnail uploadedfile-thumb"/>
<img ng-if="file.filetype=='PDF'" ng-src="images/pdf-thumb.jpg" class="img img-responsive thumbnail uploadedfile-thumb"/>
<a ng-href="http://localhost:3000/uploads/{{file.filename}}" target="_blank" class="uploaded-file-links">View</a>
<a ng-href="#" ng-click="deleteFile(file.filename);" class="uploaded-file-links">Delete</a>
</div>

Angular filter results when user clicks on repeat

I am trying to create an Angular filter that allows users to click on a record and have the filter then show only that one record within the same repeater.
For example, when a person searches for last name "knight," they see some results. Then, when the user clicks on the specific record they want, they should see only that one record displaying in the repeater.
My html is this:
<md-list-item class="md-3-line" ng-repeat="value in ctrl.results" ng-click="ctrl.showRecord(value)">
<div class="md-list-item-text" layout="column">
<h4>Employee Id: <b>{{ value.employeeId }}</b></h4>
<h4>NetId: <b>{{ value.netId }}</b></h4>
<p>Name: {{ value.preferredFirstName }} {{ value.preferredLastName }}</p>
</div>
</md-list-item>
and it passes the selected record to my controller in this function:
vm.showRecord = function (selectedRecord, ev) {
//need my filter here
};
I have looked over a number of the examples on filters, but I don't quite see how to make the filter update the very same repeat that the user clicked on.
** Edit to show answer based on Tom Chen's work **
For anyone doing this with controller as syntax, here is the answer.
html:
<md-list-item class="md-3-line" ng-repeat="value in ctrl.results | filter:ctrl.selectedId" ng-click="ctrl.showRecord(value.employeeId)">
<div class="md-list-item-text" layout="column">
<h4>Employee Id: <b>{{ value.employeeId }}</b></h4>
<h4>NetId: <b>{{ value.netId }}</b></h4>
<p>Name: {{ value.preferredFirstName }} {{ value.preferredLastName }}</p>
</div>
</md-list-item>
controller:
vm.showRecord = function (selectedRecord) {
vm.selectedId = selectedRecord;
};
You can achieve this simply by using angular filter expression like this:
<md-list-item class="md-3-line" ng-repeat="value in ctrl.results | filter:vm.selectedId" ng-click="ctrl.showRecord(value.employeeId)">
<div class="md-list-item-text" layout="column">
<h4>Employee Id: <b>{{ value.employeeId }}</b></h4>
<h4>NetId: <b>{{ value.netId }}</b></h4>
<p>Name: {{ value.preferredFirstName }} {{ value.preferredLastName }}</p>
</div>
</md-list-item>
and in your controller :
vm.showRecord = function (id) {
vm.selectedId = id;
};
UPDATED ANSWER WITH WORKING EXAMPLE
Here is an example in Plunker
You could do it with an ng-if
<md-list-item ng-if="!ctrl.selectedRecord || ctrl.selectedRecord === value" ng-repeat="value in ctrl.results" ng-click="ctrl.showRecord(value)">
...
</md-list-item>
JS
vm.showRecord = function (selectedRecord, ev) {
//if the record is already selected toggel it off
if(vm.selectedRecord === selectedRecord) {
vm.selectedRecord = undefined;
} else {
vm.selectedRecord = selectedRecord
}
};

Angular.js interpolation in filter parameter

I have a filter on a ng-repeat, which accepts a parameter. It currently works with a string.
<div ng-repeat="(key, value) in searchData | aboutFilter:'abo'">
Is is possible to use an interpolated value in place of the string?
<div ng-repeat="(key, value) in searchData | aboutFilter:'{{list.api}}'">
Here is my filter:
app.filter('aboutFilter', function() {
return function(items, input) {
var filtered = [];
angular.forEach(items, function (value,key) {
if(key===input){
filtered.push(value);
}
});
return filtered;
}
});
Here is the complete template logic:
<ul ng-repeat="list in englishList">
<a ng-class="{{list.title}}Hide" mobile-search-slide href="/about"><li><p>{{list.title}}</p><i class="fa fa-chevron-right"></i></li></a>
<ul id="hideMe" ng-class="'hide{{list.title}}'">
<div ng-cloak ng-repeat="(key, value) in searchData | aboutFilter:'{{list.api}}'">
<div ng-repeat="result in value" ng-class-odd="'odd'" ng-class-even="'even'">
<a ng-href="{{value.title}}/{{result.shortname}}">
<li>
<p>{{result.title}}</p><i class="fa fa-chevron-right"></i>
</li>
</a>
</div>
</div>
</li>
</ul>
</ul>
If you want to use some ng-modelfor filter, then you can just use the model name. No need to use {{}} expression.
In your case, it will be :
<div ng-cloak ng-repeat="(key, value) in searchData | aboutFilter:list.api">
DEMO
Remember in your filter, you are using string comparison. So the filter will check for exact matches.
And also, IN your filter:
You are comparing key with the input list.api. Here key will always be 0,1, etc index. You must be using value there instead of key

AngularJS - How to access to the next item from a ng-repeat in the controller

I'd like to access to the parameters of the next item on screen when clicking on a button.
I use a ng-repeat in my html file:
<li ng-repeat="item in items | filter:query" ng-show="isSelected($index)">
<img src="xxx.jpg" />
</li>
And the index in my Controller with a loop:
$scope.itemNext = function () {
$scope._Index = ($scope._Index < $scope.nbItems - 1) ? ++$scope._Index : 0;
$scope.functionToCallWithNextItem(nextItem.param1);
};
A simple $scope.items[$scope._Index].param1 instead of nextItem.param1 wouldn't work as the data is filtered so $index+1 from $scope.items isn't necessarily the good one.
Any idea ?
You can assign your filtered data to a variable:
<li ng-repeat="item in (filteredItems = (items | filter:query))">
Then use $index + 1 to get the next item:
<a ng-click="itemNext(filteredItems[$index + 1])">
Demo: http://plnkr.co/edit/OdL5rIxtTEHnQCC3g4LS?p=preview
It's simpy that
<div ng-repeat="item in items">
current: {{item.value}}
next: {{ items[$index + 1].value}}
previous: {{ items[$index - 1].value}}
</div>

Resources