Javascript filter array empty objects - javascript

The 1st set of code works fine and assigns non-empty objects to the var, but the 2nd code with only log the right data but will not return the data. The var just remains undefined.
Any idea on where I am going wrong? Thanks!
var filteredEmpty1 = json_data.children.filter(function(value, index, arr) {
if (value.children.length != 0) {
return value//Returns what I need
} else {
console.log("EMPTY")
};
});
json_data = filteredEmpty1;
json_data = {
"name": "RVs",
"children": json_data
};
var filteredEmpty2 = json_data.children.forEach(function(value) {
value.children.filter(function(e) {
if (e.children.length != 0) {
console.log(e)//Logs what I need to return
return(e)//Returns undefined
} else {
console.log("EMPTY")
};
});
})

Use Map instead of forEach because Map returns a value. and Filter function always returns boolean.
var filteredEmpty2 = json_data.children.map(function(value) {
return value.children.filter(function(e) {
return e.children.length != 0;
});
})

Related

Checking for empty data in JSON in JavaScript

I'm working with an API call that's returning JSON and in some scenarios some of the data is empty. For example, the snippet below shows that roleBusinessScopes is empty.
{
"userProfile": {
"organizationContacts": [
{
"roleBusinessScopes": {}
}
]
}
}
I wanted to be able to check if roleBusinessScopes is empty. I tried roleBusinessScopes.length = 0, however, that doesn't work.
When roleBusinessScopes does return data...
"roleBusinessScopes": {
"businessScopes": {
"scopeName": "something"
}
}
... I can check for that:
if (organizationContacts[i].roleBusinessScopes.businessScopes[0].scopeName !== "something")
{
// do something
}
How can I check if roleBusinessScopes has no data?
You can use Object.keys(obj).length > 0 to check if object has some keys (data) or not
if (Object.keys(organizationContacts[i].roleBusinessScopes).length > 0) {
// Not empty
} else {
// empty
}
Assuming the structure is always the same (and that you're in a ideal world where you don't need to check the validity of each property and child object), you could just check if businessScopes is not undefined.
let objectWithoutRoleBusinessScopes = {
"userProfile": {
"organizationContacts": [{
"roleBusinessScopes": {}
}]
}
};
let objectWithRoleBusinessScopes = {
"userProfile": {
"organizationContacts": [{
"roleBusinessScopes": {
"businessScopes": {
"scopeName": "something"
}
}
}]
}
};
function hasRoleBusinessScopes(objectToTest) {
return objectToTest.userProfile.organizationContacts[0].roleBusinessScopes.businessScopes != undefined;
}
console.log(hasRoleBusinessScopes(objectWithoutRoleBusinessScopes));
console.log(hasRoleBusinessScopes(objectWithRoleBusinessScopes));
You could try using Object.keys({your_object_here...}) and check the length of the returned array.
You should be able to do something like
if (Object.entries(organizationContacts[i].roleBusinessScopes).length === 0) {
// do something
}
Object.entries() will return a list of all the object's properties, which you can use to key in on length.
You could simply check if it is empty or not by this statement
if(organizationContacts[i].roleBusinessScopes === {}){
// handle empty case here
} else {
// handle non-empty case here
}
What I would use is a function to check it as there are multiple possibilities .
Sometimes a server will write null in its place so alternative checks need to be made
Us this function
function checkempty(jsonString) {
if (jsonString == null ||
jsonString == undefined ||
jsonString.length == 0) {
console.log("Name cannot be empty\n");
return false;
} else {
console.log("Your response has been recorded\n");
return true;
}
}
checkempty(Object.keys(organizationContacts[i].roleBusinessScopes))

call user function in foreach loop

i have understand that i need to change the global scope of this, because in the loop this refers to the window object. But if i try to define a variable in my foreach loop via a function its not working and i dont know why although my functio returns the correct value :(
// simple class for xml import
function io() {
this.vertexes = [];
this.getVertexByID = function(id) {
this.vertexes.forEach(function(entry) {
if (id == entry.id) {
// correct element found, displayed and returned
console.log(entry);
return entry;
}
});
}
this.importXML = function(xmlString) {
cells = this.xmlToJson(xmlString);
var parent = graph.getDefaultParent();
var _this = this;
graph.getModel().beginUpdate();
try {
// addEdges
cells.XMLInstance.Edges.Relation.forEach(function(entry) {
// both will be empty but i dont understand why :(
fromVertex = _this.getVertexByID(entry.fromNode);
toVertex = _this.getVertexByID(entry.toNode);
var e1 = graph.insertEdge(parent, null, '', fromVertex, toVertex);
});
} finally {
graph.getModel().endUpdate();
}
}
Returning a value in a forEach callback has no effect. It certainly is not the return value of the function that the forEach is part of.
So change this:
this.vertexes.forEach(function (entry) {
if(id==entry.id){
//correct element found,displayed and returned
console.log(entry);
return entry;
}
});
to this:
return this.vertexes.find(function (entry) {
return id==entry.id;
});

Evaluate passed value using .filter in JavaScript

I have a method that takes a language abbreviation and matches it using a .constant dictionary, and returns the matching language name.
How can I do an evaluation with .filter to check whether the passed isoCode/language abbreviation exists?
Here is my method:
angular.module('portalDashboardApp')
.service('ISOtoLanguageService', ['Languages', function(Languages) {
this.returnLanguage = function(isoCode) {
var categoryObject = Languages.filter(function ( categoryObject ) {
return categoryObject.code === isoCode;
})[0];
return categoryObject.name;
};
}]);
Here is the method with some error catching I have tried:
angular.module('portalDashboardApp')
.service('ISOtoLanguageService', ['Languages', function(Languages) {
this.returnLanguage = function(isoCode) {
var categoryObject = Languages.filter(function (categoryObject) {
if (isoCode != null || isoCode != undefined) {
return categoryObject.code === isoCode;
}
else {
return categoryObject.code === 'und';
}
})[0];
if (categoryObject.name != undefined || categoryObject.name != null) {
return categoryObject.name;
}
else {
return "undefined";
}
};
}]);
Thank you!
I would recommend you organize your data at Languagesin an object or map, it'll be much faster and simpler when you fetch your translation by an abbreviation. A short example:
angular.module('portalDashboardApp')
.factory('Languages', function(){
var dictionary = {
ISO: {name: 'International Organization for Standardization'}
};
return {
get: function(abbr){
return dict[abbr];
}
};
}).service('ISOtoLanguageService', ['Languages', function(Languages) {
this.returnLanguage = function(isoCode) {
if(!isoCode) {
return "Answer for empty isoCode";
}
var categoryObject = Languages.get(isoCode);
return (categoryObject || {}).name || "I don't know this abbr";
};
}]);
I'm not sure that this JS works without any syntax error (I've not try to launch it) but idea is that you don't need array and filter on big dictionaries and you are able to get any abbreviation from dict with O(1) complexity even with huge dictionary.
If you don't want to have a refactoring with your code you can do something like this:
angular.module('portalDashboardApp')
.service('ISOtoLanguageService', ['Languages', function(Languages) {
this.returnLanguage = function(isoCode) {
if (!isoCode) {
return;
}
var resultAbbrs = Languages.filter(function (categoryObject) {
return categoryObject.code === isoCode;
});
if (resultAbbrs.length > 0) {
return resultAbbrs[0].name;
}
};
}]);
In this case if isoCode is null, undefined or empty string or this key is not found in dictionary return undefined will be by default. Outside you should check a result of this function with if (result === undefined) ...
I hope it helped you)

Push element into JSON object

I want to go through a JSON, if a certain condition applies then push some extra elements in that index.
I have this JS code:
$scope.addRoleToUser = function() {
var userid = $scope.selectedUser;
var tmpdata = [];
var index = 0;
//alert(userid);
angular.forEach($scope.users, function(data) {
if (data.id == $scope.selectedUser) {
tmpdata.push(data,{"roles":[{"id":"00","name":"newrole"}]});
}
else {
tmpdata.push(data);
}
index++;
});
$scope.users = tmpdata;
};
This is my initial JSON element:
$scope.users = [
{"id":"0","name":"User1","roles":[{}]},
{"id":"1","name":"User2","roles":[{}]},
]
I'm trying to get it to look like this after the function runs:
$scope.users = [
{"id":"0","name":"User1","roles":[{"id":"00","name":"newrole"}]},
{"id":"1","name":"User2","roles":[{}]},
]
But instead I'm getting this:
[{"id":"0","name":"User1","roles":[{}]},{"roles":[{"id":"00","name":"newrole"}]},{"id":"1","name":"User2","roles":[{}]}]
Just replace this inside your function
if (data.id == $scope.selectedUser) {
data.roles = [{"id":"00","name":"newrole"}];
}
Or, if you know that roles is not empty, you can do:
if (data.id == $scope.selectedUser) {
data.roles.push({"id":"00","name":"newrole"});
}
And after this line you can add your data to tmpdata!
That snippet now will look like this:
if (data.id == $scope.selectedUser) {
data.roles = [{"id":"00","name":"newrole"}]}); //or the other one
}
tmpdata.push(data);
Inside the forEach() callback you're just working with objects and as such, you can modify them directly inside the callback:
angular.forEach($scope.users, function(data) {
if (data.id == $scope.selectedUser) {
data.roles = [{"id":"00","name":"newrole"}];
}
});
Similarly you could modify almost anything of each entry by manipulating the respective data object.
Example Fiddle
The Array.prototype.push method is variadic: (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/push).
When you call tmpdata.push(a,b,c), you are in essence appending the array [a,b,c] to tmpdata.
You can also decompose the problem with something like:
$scope.addRoleToUser = function() {
var thisUserid = $scope.selectedUser;
function addRolesFor(user) {
if (user.id === thisUserId){ user.roles = [{"id":"00","name":"newrole"}] };
return user;
}
retrun $scope.users.map(addRoles);
}
Please use the map function that is appropriate for your environment (like _.map), because the Array.prototype.map method is not supported by all browsers.

Javascript array indexOf returns undefined

When calling my function checkIss(), issFullArray.indexOf(issToCheck) always returns undefined. I've run a .length, output the contents of issFullArray, I can't figure out why it's not working- the array looks fine to me. As you can see below, I've tried explicitly setting issArray as an array and copying the array returned by my getIssList()
function updateIss() {
var issArray = [];
var currService = current.u_business_service;
var currIss = current.u_is_service;
issArray = getIssList(currService).slice(); //getIssList() returns an arry
if (checkIss(issArray, currIss) === false) {
//do stuff
}
}
function checkIss(issFullArray, issToCheck) {
if (issFullArray.indexOf(issToCheck) < 0) {
return false;
} else {
return true;
}
}
Easiest to just loop through the array and compare each value and return true if there is a match otherwise return false. Not much more code and works for all browsers.
function checkIss(issFullArray, issToCheck) {
for(i=0; i<issFullArray.length; i++) {
if(issFullArray[i]==issToCheck) {
return true;
}
}
return false;
}

Categories