Object double data binding - angularjs

I'm trying to bind a specific value of an array of objects on an ng-repeat in a table with in-line editing.
The problem that I'm encountering is that my object doesn't have the same value on each ng-repeat.
Example object:
var products = [{
id: 1,
value: 20
},
{
id: 2,
value: {
finalValue: 30,
customValue: 10
}
}];
To my knowledge if I return just the primitive value it won't be binded. I have the property names to get to the specific value on each ng-repeat. For example I have on my first iteration the way to get to the value is just value and the second one has to be value.finalValue.
To my knowledge... to bind the value I can not return just the primitive value 20 or 30, I have to return an object. So my first try was to create a function in my controller that does a property.split('.') and return an array with the object that contains the value and the property to get to it.
Eg) on my first iteration it would return:
[{ id: 1, value: 20 }, 'value']
On the second iteration it would return:
[{ finalValue: 30, customValue: 10 }, 'finalValue']
And now this will be binded to the actual model, but how can I display this on my template?
I can do something like:
<div ng-repeat="product in products>
{{ getValueObj(product) }}
</div>
But how can I display the value itself? Something like results[0][results[1]] ?

Why not on your ngRepeat do something like:
ng-repeat="product in products"
and in your binding do something like:
{{product.value.finalValue || product.value}}
The full example will be something like:
<div ng-repeat="product in products>
{{product.value.finalValue || product.value}}
</div>

Related

AngularJS ng-repeat hide items -> compare to other JSON object

I'm doing ng-repeat over an object structured like this:
Object{
id: 'id',
name: 'name'
colours:[
{
colour_id: 'id',
colour_name: 'name'
},
{
colour_id: 'id',
colour_name: 'name'
}
]
};
I have another object defined inside my controlled which is like:
Colours = {
'id1':'name1',
'id2':'name2',
'id3':'nam3',
..
};
What I wanna do in ng-repeat is that I want to compare every colours colours_id and colour_name with Colours object and check if both of values match to not show them if they already exist.
Something like
<li ng-repeat='colour in Object.colours'
ng-hide='colour.colour_id == Colours_id && colour.colour_id == Colours_name'>
</li>
The problem is, how can I 'loop' through my Colours object from controller, if it does not have id/name but the values instead? How can I compare those values?
You can try something like this:
<li ng-repeat='colour in Object.colours'
ng-hide='Colours[colour.colour_id] && Colours[colour.colour_id] == colour.colour_name'>
</li>

AngularJS RzSlider: How do I default to, if rz-slider-model is undefined or null?

I am using the Range Slider from RzSlider v2.0.1 in my application, where the rz-slider-model value can be either undefined or with an int value.
Below is my HTML template
<tr ng-repeat="feature in categories">
<td>
{{feature.featureName}}
<rzslider rz-slider-model="feature.slider.selectedMin" rz-slider-high="feature.slider.selectedMax" rz-slider-options="{floor:feature.slider.min, ceil:feature.slider.max, onChange: editor.slideChange(categoryId, feature.value, feature.slider.selectedMin, feature.slider.selectedMax)}"></rzslider>
</td>
</tr>
And the model value can be anything like these
[{
"slider": {
"min": 0,
"max": 10,
"selectedMin": 2,
"selectedMax": 4
},
"value": "1",
"featureName": "Fuel"
},
{
"slider": {
"max": 10,
"selectedMin": null,
"selectedMax": 5
},
"value": "2",
"featureName": "Large"
}]
Now, how can I default rz-slider-model value to 0 if my JSON object from API returns as null.
I tried setting something like rz-slider-model='feature.slider.selectedMin || 0' but getting an exception while changing the slider value like Error: [$compile:nonassign] Expression 'feature.slider.selectedMin || 0' used with directive 'rzslider' is non-assignable!
You can find the sample code here
Please help!
Without any further research to RzSlider the rz-slider-model has to be non-assignable to offer 2-way data-binding. This means you can't use a filter (which is what you are trying to do i think?)
The expression feature.slider.selectedMin || 0 is using the logical OR. Depending on selectedMin, it is evaluated to true/false, which is not a model the directive can work with.
I suggest you simply filter your array in your controller by injecting $filter How to use filter in controller or simply loop the array in the controller.
Example loop:
vm.myApiResponse.forEach(function(item) {
if(item.selectedMin == null) item.selectedMin = 0;
if(item.selectedMax == null) item.selectedMax = 0;
//any property which shouldn't be null
});

AngularJS: Select with ng-options- how to pass value as integer?

I am having an issue with my select form. When I select any option, the value that is being passed is of a string type, instead of number type. Here is my object that I use for ng-repeat:
$scope.apples ={
0:'Apple0',
1:'Apple1',
2:'Apple2',
3:'Apple3'
};
And here is my select, which passes string, instead of number:
<select ng-model="test" ng-options="key as value for (key,value) in apples"></select>
Any ideas?
Every time you're iterating on object fields, IMO, there is a design problem. Use an array:
$scope.apples = [
{
id: 0,
name: 'Apple0'
},
{
id: 1,
name: 'Apple1'
},
...
];
and in the view:
ng-options="apple.id as apple.name for apple in apples"
Very simple approach is to actually cast string to number (note, + operator):
ng-options="+key as value for (key,value) in apples"
It's also possible to use array as data structure:
$scope.apples = [
'Apple0',
'Apple1',
'Apple2',
'Apple3'
];
and then
ng-options="apples.indexOf(apple) as apple for apple in apples"

angularJS - How to filter by one item in object only

In this JSFiddle (https://jsfiddle.net/eug0taf9/9/), I select a rating and expect an image to be displayed.
What is happening?
When I select rating 'High', 2 images show up instead of 1 because the filter is catching category 'High' and also description 'High' of an image in category 'Low'.
What do I expect to happen?
On selecting rating "High", I only want the category to be filtered. I don't need it to be filtered by description too.
Any suggestions on how to solve this?
HTML code:
<div ng-app="myApp" ng-controller="myCtrl">
<span>Select a rating</span>
<select ng-model="catselect"
ng-options="category for category in imageCategories"
ng-change="valueSelected(catselect)">
<option value>All</option>
</select>
<!--<p>Select <input ng-model="categories"/></p>-->
<ul class="photosmenu">
<li ng-repeat="image in images | filter : catselect" ng-click="setCurrentImage(image)">
<img ng-src="{{image.image}}" alt="{{image.stars}}" width="300px"/>
</li>
</ul><!-- End of List -->
</div>
Angular Code:
var mod = angular.module("myApp", []);
mod.controller("myCtrl", function($scope){
$scope.images = [
{category: 'High', image: 'img/1.png', description: 'Random Photo', stars: '4/5'},
{category: 'Medium', image: 'img/6.png', description: 'ApplePhoto', stars: '3/5'},
{category: 'Low', image: 'img/13.png', description: 'High Top Photo', stars: '2/5'},
{category: 'None', image: 'img/16.png', description: 'Kilt Photo', stars: '0/5'}];
$scope.currentImage = $scope.images[0];
$scope.imageCategories = ["High", "Medium", "Low", "None"];
$scope.valueSelected = function (value) {
if (value === null) {
$scope.catselect = undefined;
}
};
});
That is because you have a global match filter which will match on all properties, if you want to filter on specific property set your filter object accordingly. i.e
<li ng-repeat="image in images | filter :{category: catselect}"
Demo
or you could also set your ng-model to an object,
<select ng-model="catselect.category"
and do:
<li ng-repeat="image in images | filter :catselect"
Demo
Check out documentation:
string: The string is used for matching against the contents of the array. All strings or objects with string properties in array that match this string will be returned. This also applies to nested object properties. The predicate can be negated by prefixing the string with !.
Object: A pattern object can be used to filter specific properties on objects contained by array. For example {name:"M", phone:"1"} predicate will return an array of items which have property name containing "M" and property phone containing "1". A special property name $ can be used (as in {$:"text"}) to accept a match against any property of the object or its nested object properties. That's equivalent to the simple substring match with a string as described above. The predicate can be negated by prefixing the string with !. For example {name: "!M"} predicate will return an array of items which have property name not containing "M".

How to set a custom object value in angular ng-options?

I have a array opts with the different options for a <select> element. Array's objects have a property text for display and a property value for get the value and set in a variable $scope.opt2.
Controller:
function MyCtrl($scope) {
$scope.opts = [
{value: 10, text: '1st' },
{value: 20, text: '2nd' }
];
}
I want set:
$scope.opt2 = {ref: 10} and show 1st when the first option is selected
$scope.opt2 = {ref: 20} and show 2nd when the second option is selected
I tried:
<select ng-model="opt2" ng-options="{ref: obj.value} as obj.text for obj in opts">
The value sets correctly but the text is not show. Any solution?
Examples for testing: http://codepen.io/ces/pen/azbLzX
While Philipps response will work, it's a little more complicated then you need it to be, change your select to this:
<select ng-model="opt2.ref" ng-options="obj.value as obj.text for obj in opts">
See the edited codepen here: http://codepen.io/anon/pen/XJWeVQ

Resources