Angular JS - angular.forEach - How to get key of the object? - angularjs

I have JSON object like below
{
"txt_inc_Application": {
"EWS": true,
"EWindow": true
},
"txt_inc_IncidentType": {
"Brand Damage": true,
"Internal failure": true
}
}
And I am using angular.forEach to get the values
$scope.filterFormula=function() {
angular.forEach($scope.filters, function(filterObj , filterIndex) {
angular.forEach(filterObj, function(value , key) {
console.log(value+"--"+key)
})
})
}
How can i get "txt_inc_Application" and "txt_inc_IncidentType" in the loop?
Also when call the angular function in html like below why it is getting executed twice?
{{filterFormula()}}

The first parameter to the iterator in forEach is the value and second is the key of the object.
angular.forEach(objectToIterate, function(value, key) {
/* do something for all key: value pairs */
});
In your example, the outer forEach is actually:
angular.forEach($scope.filters, function(filterObj , filterKey)

var obj = {name: 'Krishna', gender: 'male'};
angular.forEach(obj, function(value, key) {
console.log(key + ': ' + value);
});
yields the attributes of obj with their respective values:
name: Krishna
gender: male

Related

How to add dynamic property in angularjs object

I have object
$scope.postData = {
'pmu.messages.message': $scope.upd.message,
'pmu.received.id': $scope.upd.atomByReceivedBy.id,
};
and in scope there is $scope.ImageList which contains image path array
[
{ img: 'a.jpg', smallimg: 'b.jpg', smpath: 'c.jpg' },
{ img: 'a1.jpg', smallimg: 'b1.jpg', smpath: 'c1.jpg' },
];
I want to add these array value to $scope.postData field property value
as
$scope.postData = {
'pmu.messages.message': $scope.upd.message,
'pmu.received.id': $scope.upd.atomByReceivedBy.id,
'pmu.image[0].img':
'pmu.image[0].smallimg':
'pmu.image[0].smimg':
'pmu.image[1].img':
'pmu.image[1].smallimg':
'pmu.image[1].smimg':
}
How to achieve this?
Iterate $scope.ImageList and use Bracket Notation to create properties.
Here in the example, I have used just one property
$scope.ImageList.forEach(function(element, index){
$scope.postData['pmu.image[' + index +'].img'] = element.img;
});
You can iterate the array with Array.forEach, and then extract the key & value of each image using Object.entries.
$scope = {
upd: {
message: '',
atomByReceivedBy: {
id: ''
}
},
ImageList: [{
img: 'a.jpg',
smallimg: 'b.jpg',
smpath: 'c.jpg'
},
{
img: 'a1.jpg',
smallimg: 'b1.jpg',
smpath: 'c1.jpg'
},
]
}
$scope.postData = {
'pmu.messages.message': $scope.upd.message,
'pmu.received.id': $scope.upd.atomByReceivedBy.id,
};
$scope.ImageList.forEach((img, index) => {
Object.entries(img).forEach(([key, value]) => {
$scope.postData[`pmu.image[${index}].${key}`] = value;
});
});
console.log($scope.postData);

iterating through an array of objects in an object while also grabbing an outer value

I've been stuck on something simple for a little bit. I have the following response JSON:
{
"terminalName": "Montreal",
"shipThruLocationCodes":[
{
"shipThruLocationId": 112,
"shipThruLocationCode": "B84"
}
]
}
I have a select where I need to display terminalName (shipThruLocationCode) for each item in the shipThruLocationCodes array, there will only be one terminalName. The data is stored in an array in the controller called $scope.shipThrus. This is what I tried in my ng-repeat but it did not work:
data-ng-options="shipThru.terminalName for shipThru in shipThrus, item.shipThruLocationCode for item in shipThru.shipThruLocationCodes"
I think my idea is correct, but the comma (since I'm trying to display two values) is throwing an error.
So to summarize, the select should show the following for each item
"terminal Name" (shipThruLocationCode)
There will be only one terminal name and can be multiple location codes in the shipThrulocationCodes array.
Use a function to generate the options. Here's a Plunker to show you an example:
https://plnkr.co/edit/hxlowXWCS6BWh6gGfMMl?p=preview
HTML:
<select ng-model="main.selectedOption" ng-options="option.name for option in main.options"></select>
JS:
var app = angular.module('angularApp', []);
app.controller('MainCtrl', function($scope, $http) {
var vm = this;
vm.terminals = [
{
"terminalName": "Montreal",
"shipThruLocationCodes":[
{
"shipThruLocationId": 112,
"shipThruLocationCode": "B84"
}
]
},
{
"terminalName": "Somewhere else",
"shipThruLocationCodes":[
{
"shipThruLocationId": 113,
"shipThruLocationCode": "B9999"
}
]
}
];
vm.options = [];
generateOptions();
function generateOptions() {
for(var i = 0; i < vm.terminals.length; i++) {
var selectOption = {
name: vm.terminals[i].terminalName + " (" + vm.terminals[i].shipThruLocationCodes[0].shipThruLocationCode + ")"
};
vm.options.push(selectOption);
}
}
});
Check Plunker http://plnkr.co/edit/Vs2mC9zt3HmO9KGMzV6D?p=preview
If you have the list as:
$scope.shipThrus = [{
terminalName: "Montreal",
shipThruLocationCodes: [{
shipThruLocationId: 112,
shipThruLocationCode: "B84"
}, {
shipThruLocationId: 112,
shipThruLocationCode: "B89"
}]
}];
Just create this function:
function getLocationCodes(shipThru) {
return shipThru.shipThruLocationCodes.map(function(locationCode) {
return locationCode.shipThruLocationCode;
}).join(', ');
};
Which will parse the locationCodes to B84, B89.
Then parse the shipThrus:
$scope.shipThrus.forEach(function(shipThru) {
shipThru.label = shipThru.terminalName + ' (' + getLocationCodes(shipThru) + ')';
});
Now you can create the select element with the ng-options attribute as:
ng-options="shipThru.shipThruLocationCodes as shipThru.label for shipThru in shipThrus"

Error when passing filter parameter in Uigrid with cell nav

I have a editable Uigrid with ui-grid-cellnav directive to enable edit on focus. I also have a filter to display value instead of id in the dropdown.
<div ui-grid="gridOptions" ui-grid-edit ui-grid-cellnav class="grid"></div>
JS
$scope.gridOptions.columnDefs = [
{ name:'name', width:100 },
{ name:'age', width:100},
{ name: 'gender', displayName: 'Gender', editableCellTemplate: 'ui-grid/dropdownEditor', width: '20%',
cellFilter: "griddropdown:this", editDropdownIdLabel:'id',
editDropdownValueLabel: 'gender', editDropdownOptionsArray: [
{ id: 1, gender: 'male' },
{ id: 2, gender: 'female' }
] }
];
An error occurs whenever the dropdown value is modified. It seems the filter parameter is passed as a string instead of actual object, but not sure why. Works ok if I remove the cellnav directive.
Plnkr
Thanks in advance!
Interesting, I played with it a little bit and it looks like you are getting the desired results, just that occasionally ui-grid likes to pass a string as a parameter instead of the object.
If you add a check for a string in your filter it looks like you will still be getting the desired results, that's if I am understanding properly:
String check to add:
if (typeof context !== 'string') {}
Full Filter:
.filter('griddropdown', function() {
return function (input, context) {
if (typeof context !== 'string') {
var map = context.col.colDef.editDropdownOptionsArray;
var idField = context.col.colDef.editDropdownIdLabel;
var valueField = context.col.colDef.editDropdownValueLabel;
var initial = context.row.entity[context.col.field];
if (typeof map !== "undefined") {
for (var i = 0; i < map.length; i++) {
if (map[i][idField] == input) {
return map[i][valueField];
}
}
} else if (initial) {
return initial;
}
}
return input;
};
});

ngChange is not picking up changes from the model

I am trying to access the obj from the select in my controller but the only thing that I end up getting is null and undefined.
<select
ng-change="watchActions(part)"
ng-options="part.serial as part.description for part in rawBaList.items"
ng-model="currentChose"
></select>
$scope.currentChose = null;
$scope.watchActions = function (obj) {
console.log($scope.currentChose);
console.log(obj);
};
$scope.$watch('currentChose', function (newValue, oldValue) {
if(newValue){
console.log("here the new value goes");
}
});
Here is the ex of data:
{
count: 2,
items: [
{serial: 2, description: 'here is some description'},
{serial: 24, description: 'some other description'}
]
}
it was a scope issue, $parent.currentChose fixed it

angularJs filter nested object Track by

I created a custom filter, but its giving me an error
I created a fiddle here:
Fiddle
I have this user data:
data: [{
profile: {
firstName: 'John',
lastName: 'OConner'
}
}, {
profile: {
firstName: 'Smith',
lastName: 'OConner'
}
}, {
profile: {
firstName: 'James',
lastName: 'Bond'
}
}]
And I need to filter by the nested obj - profile by this
data: [{
column: {
label: 'firstName',
}
}, {
column: {
label: 'lastName',
}
}]
I can filter but is giving me this error:
this is my filter:
myApp.filter('testFilter', ['$filter',
function($filter) {
return function(items, selectedFilter) {
var returnArray = items;
var filtered = [];
var process = {};
process.filtered = [];
process.loop = function(obj, key) {
var filtered = [];
this.obj = obj;
this.key = key;
// console.log('obj--> ', obj);
// console.log('key--> ', key);
filtered = filtered.concat($filter('filter')(items, process.superFilter));
if (filtered.length > 0) {
process.filtered = filtered;
}
};
process.superFilter = function(value) {
var returnMe;
var originalValue = value.profile[process.key];
if (typeof(value) === 'String') {
originalValue = originalValue.toLowerCase();
}
if (originalValue === process.obj) {
console.log('found');
returnMe = value;
return returnMe;
}
};
if (Object.getOwnPropertyNames(selectedFilter).length !== 0) {
angular.forEach(selectedFilter, function(obj) {
filtered = filtered.concat($filter('filter')(items, obj));
});
returnArray = filtered;
// console.log('selectedFilter ', selectedFilter);
}
return returnArray;
};
}
]);
Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. How can I solve this issue?
You need to use track by as the error suggests. If you don't have a unique key to use you can use $index.
ng-repeat='talent in talents.data | testFilter:filterInput track by $index'
Here is a working example with your code: http://jsfiddle.net/hwT4P/

Resources