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

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>

Related

How to hide element if object in array is missing field

So I have an html element like this:
<div ng-hide="!myarr.length">
Im showing
</div>
Somewhere else an array is populated.
Before it is being populated it will not have a length, so the div above will not show up.
However, when the array will be filled with data (json objects) I need to understand if all the objects in the array contain a specific field (and it cannot be empty).
So my json could eventually look like this:
myarr[0] = {name: 'jack', type: ''}
myarr[1] = {name: 'jack'}
myarr[2] = {name: 'jack', type: 'mytype'}
In the case above, the div should continue to be hiding as not all the json objects contain a "type"-field that is not empty.
How do I accomplish this?
I was thinking to have an OR statement in the ng-hide. Maybe I could use the "some"-function. But when doing this it seems I cannot run this kind of function inside the ng-hide (at least my editor marks the code with red). Is there an alterntive way to do this without needing to call a function in my controller?
When you retrieve the data, you can iterate over each object in the array and examine the individual objects. If any individual object DOES NOT contain the necessary data, set the display flag to false and break out of the loop.
$scope.showElement = true;
$scope.array = [
{name: 'jack', type: ''},
{name: 'jack'}
{name: 'jack', type: 'mytype'}
];
for(let i=0; i<$scope.array.length; i++){
if($scope.array[i].type === undefined || $scope.array[i].type === ''){
$scope.showElement = false;
break;
}
}

How to update Angular scope properties when they are passed into directives?

I have functionality where developers can add custom Angular views where they can bind properties to the $scope.settings object. When clicking on the save button the $scope.settings object will be converted to JSON and saved to the database. Something like this will be the result:
{
"name": "bob",
"age": "25"
}
As long as I add elements like <input type="text" ng-model="settings.name" /> everything goes as expected.
But, now I want to add directives like this:
<umb-property property="property in properties">
<umb-editor model="property"></umb-editor>
</umb-property>
With the following code:
$scope.properties = [
{
label: 'Name',
alias: 'name',
view: 'textbox',
value: $scope.settings.name
},
{
label: 'Age',
alias: 'age',
view: 'number',
value: $scope.settings.age
}
];
The 'editor' directive loads views in place based on the 'view' property. The views are third party. The editors are loaded in a dialog. After submission of the settings dialog, the following line of code will convert the settings to JSON:
$scope.dialog = {
submit: function (model) {
var settingsJson = JSON.stringify(model.settings);
},
close: function (oldModel) {
//
}
};
In this case I cannot parse the $scope.settings to JSON, because the $scope.settings.name is not updated anymore. The $scope.editorModel.value was updated instead.
How can I bind the $scope.editorModel.value to $scope.settings.name?
I don't want to end up with a solution where I must update all $scope.settings values with the corresponding values from the editor models, because I want to support the dynamic way to convert the $scope.settings to a JSON value in the database.
For example I dont want to do: $scope.settings.name = $scope.properties[0].value
Use property accessors:
for (var i=0; i<$scope.properties.length; i++) {
$scope.settings[$scope.properties[i].alias] = $scope.properties[i].value;
};
HTML
<div ng-repeat="prop in properties">
<input ng-model="prop.value">
</div>

Convert an iterable map object to array object in ReactJS

I'm trying to load some json file in a DropdownList from react-widgets. When I load the json file the data type looks like this:
Map {size: 1, _root: ArrayMapNode, __ownerID: undefined, __hash: undefined, __altered: false}
__altered
:
false
__hash
:
undefined
__ownerID
:
undefined
_root
:
ArrayMapNode
size
:
1
__proto__
:
KeyedIterable
While the Dropdown component (from react-widgets) needs an array! So It makes this error:
Failed propType: Invalid prop `data` of type `object` supplied to `DropdownList`,
expected `array`. Check the render method of `Uncontrolled(DropdownList)`.
I can't load the json file directly and I have to use ajax to load it (or technically I can but it's a huge file and each time the user click on the dropdown list it takes couple of seconds to load the data from file). How can I convert this to an array?
P.S. The json file looks like this:
{
"items":[
{
"id": "aaa",
"name": "english"
},
{
"id": "aab",
"name": "Swedish"
},
]
}
I think you're looking for something along the lines of:
var dropdownList = jsonObject.items.map((item, i) => {
return (
<option key={i} val={item.id}>{item.name}</option>
);
})
The Array.prototype.map function simply goes over a list and produces a new list of the same size but with changes based on the modifier/callback function.
Update based on comment:
Based on the docs for DropdownList, you have two options for passing data to the list: a flat array of item names, or a list of objects with specific keys for the item name and value.
Option 1: flat list of item names
var itemNames = jsonObject.items.map((item) => item.name );
Option 2 : list of objects
var items = jsonObject.items.map((item) => {
return {
textField: item.name,
valueField: item.id
}
});
The benefit to using the second option would be when someone selects one of the items, the event that is created with point to the val attribute of the HTML <option>. This is useful for you especially since your ids and names are not the same. An example:
Option 1 (from above):
<DropwdownList
data={itemNames}
onSelect: (event) => {
// Will give the `val` attribute set by DropdownList
// This might be the item name, or it might be something unique to DrowdownList
console.log(event.target.value);
}
/>
Option 2 (from above):
<DropwdownList
data={items}
onSelect: (event) => {
// Will give the `valueField` attribute you set, which for you is the item's `id` field
// This might be the item name, or it might be something unique to DrowdownList
console.log(event.target.value);
}
/>

How to reference a value of an object by property?

I have an angularjs object like this:
$scope.afterLogin = [
{value: 'customers|follow-ups', text: 'Follow Ups'},
{value: '', text: 'not set'}
];
I'm trying to use it with xeditable as follows:
<span
editable-select="user.default_module"
e-ng-options="s.value as s.text for s in afterLogin"
e-name="default_module"
e-form="rowform">{{s[user.default_module] as s.text for s in afterLogin}}</span>
What I am trying is to show the text-property in afterLogin that is defined by user.default_module. What am I doing wrong? I am getting parse errors on s[user.default_module] as - how do I reference a property of an object in this scope?
Note: this is wrapped with ng-repeat="user in users".
You are trying to display currently selected value in a very strage way. In the official example they are using filter for this purpose. However, you can simplify it by builing a value: label map, i.e.:
$scope.afterLoginLabels = {};
for (var i = 0; i < $scope.afterLogin.length; i++) {
$scope.afterLoginLabels[$scope.afterLogin[i].value] = $scope.afterLogin[i].text;
}
Then, display text value as:
<span [...]>{{ afterLoginLabels[user.default_module] }}</span>
See JSFiddle.

Object double data binding

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>

Resources