How to update object except current index in Angular 8 - javascript

this.StaticData = {
"values": [
{
"value": "test",
"label": "test"
},
{
"value": "aa",
"label": "bb"
},
{
"value": "cc",
"label": "dd"
}
]
};
I have above object of data. I wanted to return all object except currentIndex.
For example -
suppose in above objects, if I am going to edit 0th index values,
and I have updated "value": "rest", instead of "value": "test" and
"label": "test" need to keep as it is. So in that case,
it will allow to update the values.
{
"value": "rest",
"label": "test"
},
But if I tried to enter "label": "bb" and "label": "dd",
so it will return false, because these values are already available in above objects.
isLabelExist() {
const formData = this.editStaticParametersForm.value;
const currentIndex: number = this.StaticData.values.indexOf(this.selectedRowValue);
if (formData.label_value && this.StaticData) {
var isPresent = this.StaticData.values.some(function (el) {
return el.label === formData.label_value
});
if (isPresent) {
return false;
}
}
return true;
}

using find (or some) you can check the "index" (add a second argument to the function find), so,
var isPresent = this.StaticData.values.some(function (el,i) {
return el.label === formData.label_value && i!=currentIndex
});
Really in .ts we use arrow flat and use const or let, not var
const isPresent = this.StaticData.values.some((el,i)=> {
return el.label === formData.label_value && i!=currentIndex
});
Or
const isPresent = this.StaticData.values.some(
(el,i)=> el.label === formData.label_value && i!=currentIndex);

Related

JS: Check for existence of deep object key and replace value

I am wanting to develop a function to check for the existence of a key within a deep object and then replace the value of that key with a data set from another object.
E.g.
var obj = {
"id": 1,
"component": "Preset 1",
"priority": 1,
"header": {
"modeSet": 2
}
}
const modeSets = [
{
"id": 1
"name": "Mode Set 1"
},
{
"id": 2
"name": "Mode Set 2"
}
]
function obtainModeSets(obj){
//...
}
When the function obtainModeSets runs I'd like to mutate obj so that the value of modeSet within obj equals { "id": 2 "name": "Mode Set 2" }
Does anyone have any suggestions? Thanks
You can use recursion like this
const obj = {
"id": 1,
"component": "Preset 1",
"priority": 1,
"header": {
"modeSet": 2
}
}
const modeSets = [{
"id": 1,
"name": "Mode Set 1"
},
{
"id": 2,
"name": "Mode Set 2"
}
]
function obtainModeSets(obj) {
Object.entries(obj).forEach(([key, value]) => {
if (key === "modeSet") {
obj[key] = modeSets.find(set => set.id === value)
return
}
if (typeof value === "object") {
obtainModeSets(value)
}
})
}
obtainModeSets(obj)
console.log(obj)
I think something like the below code maybe solves your problem. I don't know what you mean exactly. But based on the showing example, I guess you need to replace your key with the id provided in the modeSets.
function obtainModeSets(obj, key, cb){
// loop through all possible keys
Object.keys(obj).forEach(k => {
if (key === k) {
obj[k] = cb(obj[k])
}
// if the value of the key is object, just go inside
if (typeof obj[k] === "object") {
obtainModeSets(obj[k], key, cb)
}
})
}
// you can call your function like this
obtainModeSets(obj, 'modeSet', (val) => {
return modeSets.find(mode => mode.id === val)
})

Get values for a matching key recursively from object

I have this json object
{
"data": {
"user": {
"user_info": {
"id": "AoGC2HQ9vedHmzcMX"
},
"product": [
{
"node": {
"id": "NzcxNzU2ODU1ODM1",
"feedback": {
"raters": {
"nodes": [
{
"id": "1",
"name": "Dan"
},
{
"id": "2",
"name": "Allen"
},
{
"id": "3",
"name": "Williams"
}
]
},
"commentors": {
"nodes": [
{
"id": "001",
"name": "Kent"
},
{
"id": "002",
"name": "Jay"
}
]
}
}
}
}
]
}
}
}
So how do I make it to get values of id If the parent property matches the desired key name, In this example I want to get all id's from raters.nodes only.
so expected result is
[1,2,3]
I know can do obj.data.user.product[0].node.feedback.raters.nodes and loop through that, but that is not how I want and the object tree occasionally changes.
I have used this recursive function
const recursiveSearch = (obj, searchKey, results = []) => {
const r = results;
Object.keys(obj).forEach(key => {
const value = obj[key];
if(key === searchKey && typeof value !== 'object'){
r.push(value);
}else if(typeof value === 'object'){
recursiveSearch(value, searchKey, r);
}
});
return r;
};
//returns all id's
While it works, it returns all id values, so how do I improve it? If not, how do I make this possible?
I think you want to really do this in 2 steps,..
First make a function to get the root node your looking for, and then you can just use map like normal.
Below is an example.
var data = JSON.parse("{\"data\":{\"user\":{\"user_info\":{\"id\":\"AoGC2HQ9vedHmzcMX\"},\"product\":[{\"node\":{\"id\":\"NzcxNzU2ODU1ODM1\",\"feedback\":{\"raters\":{\"nodes\":[{\"id\":\"1\",\"name\":\"Dan\"},{\"id\":\"2\",\"name\":\"Allen\"},{\"id\":\"3\",\"name\":\"Williams\"}]},\"commentors\":{\"nodes\":[{\"id\":\"001\",\"name\":\"Kent\"},{\"id\":\"002\",\"name\":\"Jay\"}]}}}}]}}}");
function getRoot(data, search) {
function get(path, data) {
for (const [k, v] of Object.entries(data)) {
if (v instanceof Object) {
const pp = `${path}.${k}`;
if (pp.slice(-search.length) === search) {
return v;
}
const r = get(`${path}.${k}`, v);
if (r) return r;
}
}
}
return get('', data);
}
const r = getRoot(data, 'raters.nodes');
console.log(r && r.map(i => i.id));

Read specific value of an object

I'm using an api that return this object:
{
"0155894402285712": { "type": "GBUserFieldText", "value": "A0242", "name": "Codice+tessera" },
"0155894402283800": { "type": "GBUserFieldText", "value": "LZZMRN55L53C003Z", "name": "Codice+Fiscale" }
}
I need to extract the value A0242 and LZZMRN55L53C003Z but the only things that I know are the name "Codice+tessera" and "Codice+fiscale". How can I read these values? Maybe my question is stupid but really I'm losing my brain today...
Thanks
You can try this:
const data = {
"0155894402285712": {
"type": "GBUserFieldText",
"value": "A0242",
"name": "Codice+tessera"
},
"0155894402283800": {
"type": "GBUserFieldText",
"value": "LZZMRN55L53C003Z",
"name": "Codice+Fiscale"
}
};
// get an array of all the values of this data.
const arrayOfValues = Object.values(data);
// filter this array in order to find the one which the name you want
const selectedObj = arrayOfValues.find(obj => obj.name === 'Codice+tessera');
// get the value of this object.
const selectedValue = selectedObj.value;
console.log(selectedValue);
// You can also make a function findValueOf(name):
const findValueOf = name =>
arrayOfValues.find(obj => obj.name === name) &&
arrayOfValues.find(obj => obj.name === name).value;
// and use it for example:
console.log(findValueOf('Codice+tessera')); // "A0242"
console.log(findValueOf('Codice+Fiscale')); // "LZZMRN55L53C003Z"
You can use Object.values and then access value key's value
let obj = {
"0155894402285712": { "type": "GBUserFieldText", "value": "A0242", "name": "Codice+tessera" },
"0155894402283800": { "type": "GBUserFieldText", "value": "LZZMRN55L53C003Z", "name": "Codice+Fiscale" }
}
Object.values(obj).forEach(({value})=>{
console.log(value)
})
You can use Object.values to convert the object into an array. Use map to loop and get the value
var obj = {"0155894402285712":{"type":"GBUserFieldText","value":"A0242","name":"Codice+tessera"},"0155894402283800":{"type":"GBUserFieldText","value":"LZZMRN55L53C003Z","name":"Codice+Fiscale"}}
var resut = Object.values(obj).map(o => o.value);
console.log(resut);
If you want to match the name and value, you can use reduce
var obj = {"0155894402285712":{"type":"GBUserFieldText","value":"A0242","name":"Codice+tessera"},"0155894402283800":{"type":"GBUserFieldText","value":"LZZMRN55L53C003Z","name":"Codice+Fiscale"}}
var resut = Object.values(obj).reduce((c, v) => Object.assign(c, {[v.name]: v.value}), {});
console.log(resut);
If you are looking to find A0242 from the value "Codice+tessera" that you have, you need something different than the other answers:
var data = {
"0155894402285712": { "type": "GBUserFieldText", "value": "A0242", "name": "Codice+tessera" },
"0155894402283800": { "type": "GBUserFieldText", "value": "LZZMRN55L53C003Z", "name": "Codice+Fiscale" }
}
const values = ["Codice+tessera", "Codice+fiscale"]
const results = values.map(v => Object.values(data).find(datum => datum.name === v)).map(v => v.value)
console.log(results) // [ "A0242", "LZZMRN55L53C003Z" ]

Recursive function not returning Label in javascript

I'm trying to return the Label match however I seem to be doing something wrong here. Can someone push me in the right direction?
console.log('start');
var test = {
"ID": 234324,
"Label": "KDF",
"children": [{
"ID": 234234,
"Label": "KJDF",
"children": [{
"ID": 234324,
"Label": "KJDF"
}, {
"ID": 22323,
"Label": "LKNDF"
}, {
"ID": 34535,
"Label": "LKNSF"
}]
}, {
"ID": 323434,
"Label": "CLK"
}]
}
function testThis(thing, ID) {
if (thing.ID == ID) {
console.log('match!')
return thing.Label;
} else if (thing.children && thing.children.length) {
thing.children.forEach(function(x) {
console.log(x);
return testThis(x, ID);
})
return false;
} else {
return false;
}
}
console.log(testThis(test, 323434));
console.log('end');
Where you do
thing.children.forEach(function(x) {
use .some() instead of .forEach(), like this
return thing.children.some(function(x) {})
.forEach() returns undefined, while .some() will return either true or false and will stop iterating once trueis returned.
some() executes the callback function once for each element present in the array until it finds one where callback returns a true value. If such an element is found, some() immediately returns true. Otherwise, some() returns false.
Fiddle: https://jsfiddle.net/mkarajohn/7ebr6pna/
You don't need to use foreach for that, use a normal for like this
function testThis(thing, ID) {
if (thing.ID == ID) {
return thing.Label;
} else if (thing.children && thing.children.length) {
var label;
var length = thing.children.length
for(var i = 0; i < length; i++) {
label = testThis(thing.children[i], ID);
if(label) {
return label;
}
}
}
return false;
}
You're expecting forEach to return something and leave the loop. It always returns undefined and always iterates every element.
forEach() executes the callback function once for each array element;
unlike map() or reduce() it always returns the value undefined and is
not chainable. The typical use case is to execute side effects at the
end of a chain.
See MDN forEach
The Array.prototype.some() might serve you better since it will only execute some of the elements and returns a value.
See working code below:
console.log('start');
var test = {
"ID": 1,
"Label": "A",
"children": [{
"ID": 2,
"Label": "B",
"children": [{
"ID": 5,
"Label": "E"
}, {
"ID": 6,
"Label": "F"
}, {
"ID": 7,
"Label": "G"
}]
}, {
"ID": 3,
"Label": "C"
}, {
"ID": 4,
"Label": "D",
"children": [{
"ID": 8,
"Label": "H"
}, {
"ID": 9,
"Label": "I"
}]
}]
}
function testThis(thing, ID) {
if (thing.ID == ID) {
console.log('match!')
return thing.Label;
} else if (thing.children && thing.children.length) {
var theone = null;
thing.children.some(function(x) {
theone = testThis(x, ID);
return theone;
})
return theone;
} else {
return false;
}
}
alert(testThis(test, 5));
console.log('end');

Removing Duplicate object from array in jquery code not working

This is my array in jquery , which contains duplicate objects/elements :
[{
"name": "hello",
"label": "world"
}, {
"name": "abc",
"label": "xyz"
}, {
"name": "hello",
"label": "world"
}]
I am using the following piece of code to remove duplicate elements but it not working the duplicate elements are not removed.
var result = [];
$.each(subservices, function (i, e) {
if ($.inArray(e, result) == -1)
result.push(e);
});
alert(JSON.stringify(result));
Function $.inArray works fine for simple types (e.g. number or string), but for complex types it does not produce the correct result, because it tries to match by reference. Instead of using inArray in your loop you can search the array using function grep:
var subservices = [{
"name": "hello",
"label": "world"
}, {
"name": "abc",
"label": "xyz"
}, {
"name": "hello",
"label": "world"
}
];
var result = [];
$.each(subservices, function (i, e) {
var matchingItems = $.grep(result, function (item) {
return item.name === e.name && item.label === e.label;
});
if (matchingItems.length === 0){
result.push(e);
}
});
//displays result [{"name":"hello","label":"world"},{"name":"abc","label":"xyz"}]
alert(JSON.stringify(result));
Here is a working jsFiddle
You need to filter array by unique name/value. Here is some pure JS solution:
var data = [{
"name": "hello",
"label": "world"
}, {
"name": "abc",
"label": "xyz"
}, {
"name": "hello",
"label": "world"
}];
var result = data.filter(function(el, i, x) {
return x.some(function(obj, j) {
return obj.name === el.name && (x = j);
}) && i == x;
});
alert(JSON.stringify(result, null, 4));
This is because these two objects are distinct, even though all the attributes inside are the same. You can see this from:
console.log(result[0] === result[2]);
which results in false.
Instead, you need to iterate through your array based on a unique identifier, such as name & label as such:
for(var i = 0, i < results.length; i++) {
if (result[i].name === ... && result[i].label === ...) {
index = i;
break;
}
}
to check if your item is unique.

Categories

Resources