forEach function in typescript - javascript

I am working with graphql returned data that looks like this:
"userRelations": [
{
"relatedUser": {
"id": 4,
"firstName": "Jack",
"lastName": "Miller"
},
"type": "FRIEND"
},
{
"relatedUser": {
"id": 3,
"firstName": "Rhena",
"lastName": "Tahoma"
},
"type": "CONTACT"
}
]
I had to separate all those items which had the type: "FRIENDS". I did this and it worked perfectly:
var friendArray = new Array();
for (let i in data.users.nodes[0].userRelations) {
if (data.users.nodes[0].userRelations[i].type == "FRIEND")
{
friendArray.push(data.users.nodes[0].userRelations[i]);
}
}
However, I read that using for loops and for in is not a good idea. Is there any other way to iterate and check all the objects without for loops? I tried using this but it doesn't give the correct results:
data.users.nodes[0].userRelations.forEach((object: Object)=> {
if (data.users.nodes[0].userRelations.type == "FRIEND")
{
friendArray.push(data.users.nodes[0].userRelations.object);
}
})
The friendsArray remains empty. What am I missing out?
Edit:
After filtering the friends data, I want to render some items by mapping. I was trying to do something like this:
data.users.nodes[0].userRelations.map()
data.users.nodes[0].userRelations.filter(({ type }) => type === 'FRIEND').map(/*code*/)
but this gave me an error that:
Binding element 'type' implicitly has an 'any' type.ts(7031)

In your case I would use filter:
var result = data.users.nodes[0].userRelations.filter(element=>element.type=="FRIEND");

First of all, using a for loop there is fine.
If you want to use foreach, you'll need to use the object element you create in the forEach callback. That's the advantage of using foreach.
data.users.nodes[0].userRelations.forEach((object: Object)=> {
if (object.type == "FRIEND")
{
friendArray.push(object);
}
})
If you want to improve the function, you may want to use a .filter, which is probably the cleanest way of solving this.

Have a look at array.filter(), you can do const friends = data.users.nodes[0].userRelations.filter(userRelation => userRelation.type === 'FRIEND") but to your current code, you could change your if statement to be - if(object.type==='FRIEND')

data.users.nodes[0].userRelations.forEach((o: Object)=> {
if (o.type == "FRIEND")
{
friendArray.push(o);
}
})

Related

Alternative way to remove object from an array of json objects other than splice

I am still fairly new to JavaScript and I need help with an issue I am having.
I have a Java function that returns an array of json objects as such:
{
"payload": {
"phone": "1234567890",
"email": "test#test.com",
"contact": {
"personal": "test test",
"professional": "professionaltest test"
}
}
}
Now I have various scenarios in my API test where I am sending a POST request but purposefully missing some of the key/value pairs in the json. Such as:
Send the request by skipping contact.
Send the request by skipping phone.
etc.
I have researched and it seems that using .splice can be used to remove an object. However, from what I understand, the removal criteria is primarily driven by indexes (indices?). I'd rather not use remove by index in case something changes the output of the function in the future. Is there a way to remove by key name? Any alternative methods would be greatly appreciated too.
This is my favorite way to remove an value from an object.
For example, you want to remove phone from the payload object.
var { payload } = // your object
var { phone, ...newValue } = payload
console.log(newValue)
newValue is an copy of payload object without the phone key value.
function removeByKeys(obj, keys) {
return Object.keys(obj).reduce((newObj, key) => {
if (keys.includes(key)) {
return newObj;
}
return { ...newObj, [key]: obj[key] };
}, {});
}
const person = { name: 'bob', age: 36 };
removeByKeys(person, ['age']); // { name: 'bob' }
The has the same API as lodash omit. https://lodash.com/docs/4.17.15#omit. You can use that if you have more complicated use-cases, but the above is simple enough.

Push values from nested objects

I would like to know the best method for grabbing values from nested objects like this one:
var object = {
1: {
1: {
"names": "bob"
},
2: {
"names": "jim"
}
}
}
What function or loop would I write to push the values “bob” and “Jim” into an array?
Thank you in advance!
you can use Object.values + map
Object.values(object[1]).map(p => p.names)

How can I remove null from JSON object with AngularJS?

I'm trying to remove an object from Json Object it works..but it replace it with null..i dont know why, how can i remove the null value from the json..heres the function :
company.deleteExternalLinkFromGrid = function (row, matricule) {
// console.log('Inside of deleteModal, code = ' + code);
//$scope.sitting= {};
console.log(matricule);
//console.log(JSON.stringify(linkJsonObj));
delete linkJsonObj[matricule];
console.log(JSON.stringify(linkJsonObj));
};
heres the object:
[{"name":"xxx","link":"www.ddd.com","id":0,"$$hashKey":"uiGrid-001Z"},null,null]
You can use filter(), x will be without null's.
function test()
{
var x =[{"name":"xxx","link":"www.ddd.com","id":0,"$$hashKey":"uiGrid-001Z"},null,null].filter(isNotNull);
alert(JSON.stringify(x));
}
function isNotNull(value) {
return value != null;
}
fiddle
There are multiple ways to delete an object from an array of objects in JavaScript. You don't need AngularJS for that, you can use VanillaJS.
If you just want the nulls filtered you can use
var yourArray =[{"name":"xxx","link":"www.ddd.com","id":0,"$$hashKey":"uiGrid-001Z"},null,null];
yourArray = yourArray.filter(function(elt){
return elt != null;
});
But this loses the original reference to your object.
If you want to keep the reference, Use array.splice().
yourArray.forEach(function(){
yourArray.splice(yourArray.indexOf(null),1);
});
now you will have null less array in yourArray. This actually deletes an object from an array without changing the reference,
delete will replaced the object with undefined
You can filter the array to remove them using Array#filter()
var array = [{
"name": "xxx",
"link": "www.ddd.com",
"id": 0,
"$$hashKey": "uiGid-001Z"
}, {
"name": "xx",
"link": "www.dddcom",
"id": 1,
"$$hashey": "uiGrid-0029"
}, {
"name": "xxx",
"link": "www.ddd.com",
"id": 2
}];
delete array[1];
array = array.filter(a=>a);
console.log(JSON.stringify(array));

How to check if array attribute from JSON object is empty?

I've this kind of JSON object :
sections:
[
{
"id":1,
"title":"Description du projet",
"content":[
{
label:'Type de projet',
type:'select',
values:[
{
label:'Achat',
options:[
{
label:'Neuf'
},
{
label:'Neuf + travaux'
},
{
label:'Ancien'
},
{
label:'Ancien + travaux'
},
{
label:'Terrain'
},
{
label:'Terrain + construction'
}
]
},
And I would like to check if the "options" array is define or not in order to build different component in each case.
Is it possible ? If yes can you tell me how ?
Thank you in advance
Iterate each array from "sections" until "values", then we will do the checking there. See these code:
sections.forEach(section =>{
section.content.forEach(c => {
c.values.forEach(value =>{
if (!value.options) {
// "options" array is undefined.
return;
}
// "options" array is defined, build different components here.
});
});
});
You can use lodash to do all the undefined or exists checks. Check out the library here
Coming to your question, using lodash I'd do something like this:
import _ from 'lodash';
let options = _.get(a, ['sections','0','content', '0', 'values', '0', 'options']);
if(!_.isUndefined(options)){
//do your stuff
}
You can do this in many ways using lodash. You can also get default value back if the path doesn't exist.

Underscore recursive groupBy array of string arrays

I'm trying to combine and group an array with a bunch of flat arrays that contain only strings, no objects.
So my array looks something like this:
var array = [
["MotherNode", "Node1", "ChildNode1", "ChildOfChildNode1"],
["MotherNode", "Node1", "ChildNode2", "ChildOfChildNode2"],
["MotherNode", "Node2", "ChildNode3", "ChildOfChildNode3"],
["MotherNode", "Node2", "ChildNode3", "ChildOfChildNode4"],
["MotherNode", "Node3", "ChildNode4", "ChildOfChildNode5"],
["MotherNode", "Node3", "ChildNode4", "ChildOfChildNode5"]
]
Im doing this in javascript/angularjs and so far I've gathered that the best solution is probably to use underscore.js groupBy/combine methods. However most of the examples that i can find are dealing with arrays of objects where they can group them together by using a value's key. And I'm not good enough with algorithms yet to be able to figure this out on my own.
The array I'm dealing with can have hundreds of values and the result array could get 5-10 levels deep.
The result I'd like by parsing the above array would look something like this:
var result= {
"MotherNode": [{
"Node1":[{
"ChildNode1":"ChildOfChildNode1"
},{
"ChildNode2":"ChildOfChildNode2"
},{
"Node2":[{
"ChildNode3":["ChildOfChildNode3","ChildOfChildNode4"]
},{
"Node3":[{
"ChildNode4":"ChildOfChildNode5"
}
]
}
So does anyone have any clue how this can be done? I'm completely out of ideas.
I solved this using _.reduce grouping wasnt the way to go
var result = _.reduce(array,function(memo, val){
var tmp = memo;
_.each(val, function(fldr){
if(!_.has(tmp, fldr)){
tmp[fldr] = {}
}
tmp = tmp[fldr]
})
return memo
},{})
the end leaf wont be set as a value but it should be easy to change that behavior to whatever suits you use case
{ MotherNode:
{ Node1:
{ ChildNode1: { ChildOfChildNode1: {} },
ChildNode2: { ChildOfChildNode2: {} } },
Node2: { ChildNode3: { ChildOfChildNode3: {}, ChildOfChildNode4: {} } },
Node3: { ChildNode4: { ChildOfChildNode5: {} } } } }

Categories