find if path exists in json nodejs - javascript

I would like to add to the an existing json a new value in the following path:
 
VAL:"BS", PATH:["info", "bosses", "lives"]
if my json had the passes it will add the value, otherwise I will create the fields
example:
var myJson = {
    "root": {
        "name": "jim",
        "age": "4",
        "info": {"bosses": {"name": "sam"}}
    }
}
so my new json will look like this:
var myNewJson = {
    "root": {
        "name": "jim",
        "age": "4",
        "info": {"bosses": {"name": "sam", "lives": "BS"}}
    }
}
an example when I didn't have the fields:
var myJson = {
    "root": {
        "name": "jim",
        "age": "4",
    }
}
the output:
var myNewJson = {
    "root": {
        "name": "jim",
        "age": "4",
        "info": {"bosses": {"lives": "BS"}}
    }
}
an example where part of the path exists I didn't have the fields:
var myJson = {
    "root": {
        "name": "jim",
        "age": "4",
 "info": {"salary": 500}
    }
}
the output:
var myNewJson = {
    "root": {
        "name": "jim",
        "age": "4",
        "info": {"salary": 500, "bosses": {"lives": "BS"}}
    }
}
how can I check if path exists (note: part of the path might exist- how can I know from where to start it?)

This is old, but...
testing existence of fields on paths is nicer now, with optional chaining, like:
var infoExists = !!myJson?.root?.info - the ?. means that if root were missing, the line wouldn't break.
In this case though, I wouldn't worry about testing for the existence of fields, I'd use spread operators to just rebuild the info object:
var newInfo = {"bosses": {"lives": "BS"}};
var info = {...myJson.root.info, ...newInfo};
if myJson.root.info doesn't exist, no problem (as long as myJson.root does, cue an optional chaining check?), we just get the newInfo.
if myJson.root.info currently holds {"salary": 500}, the spread operators will combine that to "info":{"salary": 500, "lives": "BS"}.
if myJson.root.info currently holds the same as newInfo, well, no sweat, we end up with no change.
Now you have the info object exactly as you want it, you can simply replace it in the original object with
myJson.root.info = ...info;

The first thing you could think it works could be some code like:
if (myObject.attributeName){
//property exists!
}
It will work for you in many tests but I sure you know that javascript manage some values as truthy or falsy. It use lot's of different type value as boolean false in many comparison (just === not convert type).
When you check something as
if(somethingtotest){
// it's true
}
It is the same you'd write
if(somethingtotest == true){
// it's true
}
'==' operator tryes to convert different types to be "similar" together.
In the first example code many of object attribute values can be '==' true.
That attribute value is truthy, meaning it’s an object, a non-empty string, a non-zero number that’s not NaN, true, and not null or undefined.
That means if the attribute is an empty string (“”), this check will fail. The same if value is 0 (zero), null, false. Failing, in this case, doesn’t mean that the property doesn’t exist. In fact, the property does exist and contains a value, but the value is falsy and so doesn’t pass this test.
Since ECMAScript 5 the base Object has the function hasOwnProperty(propertyName)
So you could try
if(myObject.hasOwnPorperty('attributeName')){
// do something
}
This function remembers us that the Objects has also prototype attributes that our object could inherit. For example if I write
myObject.anyAttribute='AnyValue';
var my1stObject = Object.create(myObject);
var my2ndObject = Object.create(myObject);
myObject.anyAttribute='AnotherValue';
console.log(my1stObject.anyAttribute);
console.log(my2ndObject.anyAttribute);
last two rows will print 'AnotherAttribute'.
In this case 1st and 2nd objects have not own property anyAttribute but they will use the prototipe one.
Different if you write
myObject.anyAttribute='AnyValue';
var my1stObject = Object.create(myObject);
var my2ndObject = Object.create(myObject);
my1stObject.anyAttribute='AnotherValue';
console.log(my1stObject.anyAttribute); //AnotherValue
console.log(my2ndObject.anyAttribute); //AnyValue
First object hasOwnProperty 'anyAttribute' because we set it.
At last, to be shure to check if property, proptotipe or own, really exists, you would like to use
if('anyProperty' in myObject){
//do something
}
I suggest you to read it better at this link:
https://www.nczonline.net/blog/2010/07/27/determining-if-an-object-property-exists/

Related

How does destructuring assignment evaluate the result in my case?

I have following javascript code,
op = [
{busiCode:"001",
busiName:"Order"
},
{busiCode:"002",
busiName:"Plan"
}
]
const [{ busiCode = '' } = {}] = op
console.log(busiCode)
It prints 001, I would ask how javascript evaluate the reuslt in the above code,
Thanks!
The source value is an array. Thus, in the const declaration, the first [ says "look inside the array"
const [ // plz look in array
Then, in the source, the elements of the array (well, the first one at least), are objects. Thus in the declaration the first { means "in the first element of the array, treat it as an object and look inside".
const [{ // plz look in object at array[0]
Then, the identifier busiCode says that you want it to look for a property called "busiCode" in the object in the array, and that you want a local constant with that name ("busiCode") and the value of that property in that first object in the array.
const [{ busiCode // plz get "busiCode" property
Then the = '' means "if you can't find busiCode as a property just give me an empty string".
const [{ busiCode = '' // default to empty string if not found
Then the object "lookup" part is completed with }, and = {} means that if the original array has no first element, do all that stuff with a dummy empty object".
const [{ busiCode = '' } = {} // give me at least an empty string
The pattern of the left side of the destructuring matches the general "shape" of the right-hand side.

Javascript Filtering JSON data

Sample JSON data:
{
"assignments": [{
"date": "2022-04-01",
"lName": "lastname",
"uId": "12345",
"uCode": "LName1",
"fName": "FName1 ",
"aName": "AsignmentName1",
"aId": "998"
}]
}
I'd like to filter the following data to get a specific element's contents based on searching for an assignment name.
For instance in SQL like terms
Select * FROM assignments WHERE `aName` = 'AssignmentName1'
I'm sure this is simple but having trouble with methods for how to accomplish it.
Thanks
I am new here, but if you have access to modern day JavaScript, I would do something like:
const data = JSON.parse('{"assignments":[{"date":"2022-04-01","lName":"lastname","uId":"12345","uCode":"LName1","fName":"FName1 ","aName":"AsignmentName1","aId":"998"}]}';
const yourMatch = data.assignments.find(c => c.aName === 'AssignmentName1');
Since data.assignments is an array, you can call the find() function on it. This functions takes a 'search'-function/lambda as argument.
This search function basically takes an element and decides, whether it is the one you search for, or not aka it returns a boolean.
In my example the arrow function is c => c.aName === 'AssignmentName1', which is shorter and easier to read than a normal function definition. (You can call c whatever you want, it's just cleaner this way.)
You can exchange find() with filter(), if you accept multiple results and not just the first one.
You first have to parse the JSON string:
const parsedJSON = JSON.parse(jsonString);
The object returned is contains all the data from your JSON string. To access the assignments array you can use dot notation.
const assignments = parsedJSON.assignments;
If you don't need to support old browsers, ES6 has a handy function for finding the value in an object. Use the "find"-function and pass a function that returns true for the item you are looking for:
const selectedAssignment = assignments.find( (assignment)=> {
return assignment.aName=="AssignmentName2";
});
If you don't want to use ES6 you can use a for loop.
var assignments = JSON.parse(jsonString).assignments;
function getAssignmentWithName(name) {
for (var i = 0; i < assignments.length; i++) {
if (assignments[i].aName == name) {
return assignments[i];
}
}
return false;
}
var selectedAssignment = getAssignmentWithName("AssignmentName1");

How to grab the children of an Object.keys(myEl) reference

In the code below, I can get a reference to the text000 object, but I need to capture its child array as my target payload. Once I have a reference to the key, how can I capture its children?
Full object is below:
activeItem = [{"dnd":{"index":0,"active":true,"group":"common","label":"Text (000)","type":"text"},
"json":{"schema":{"properties":{"text000":{"title":"Text (000)","type":"string"}},"required":["text000"]},"layout":[{"key":"text000","description":"","floatLabel":"auto","validationMessages":{"required":"Required"}}]}}]
To grab a reference to the "text000" key I'm using:
const myEl = Object.keys(this.activeItem.json.schema.properties); // points to text000
I need to pull that key's contents/children > {"title":"Text (000)","type":"string"} out to use it as my target payload for this operation.
The text000 element is dynamic so I need its reference, which is why I'm using the Object.keys() method to point to it.
Feel free to school me on the proper names to use to refer to these elements. For example, not sure exactly how to reference > {"title":"Text (000)","type":"string"} with respect to the key text000. Is that the key's "children", "value", "contents" or what?
UPDATE:
console.log('TRY: ', this.activeItem.json.schema.properties[0]);
// Returns undefined
console.log('TRY2: ', this.activeItem.json.schema.properties);
// Returns {"text000":{"title":"Text (000)","type":"string"}}
I need something to return:
{"title":"Text (000)","type":"string"}
SOLUTION thanks #jaredgorski:
const properties = this.activeItem.json.schema.properties;
const propertiesKeys = Object.keys(properties);
const propertiesKeysFirstVal = Object.keys(properties)[0];
const logProperties = properties[propertiesKeysFirstVal];
console.log('PROPERTIES KEYS:', propertiesKeys);
console.log(
'VALUES OF FIRST PROPERTIES KEY:',
propertiesKeysFirstVal
);
console.log('RESULT:', logProperties);
PROPERTIES KEYS: ["text000"]
wrux-wrux-form-builder.js:1782 VALUES OF FIRST PROPERTIES KEY: text000
wrux-wrux-form-builder.js:1783 RESULT: {title: "Text (000)", type: "string"}
You need to remember that activeItem is an array. As long as you include the index (in this case the first index, which is [0]), you can access the json property (or key) and continue down the chain to retrieve the values in text000.
The other trick here is that you're wanting to access the first key in properties, but you don't know the name of that key yet. So what you need to do is actually make an array of the keys and then find out the name of the first key in that properties object. To do this, you can use Object.keys(), a method which turns the keys of an object into an array. Once you have the name of this key, you only need to use bracket notation on the properties object to find the value for this key. I'll show you how this works in the snippet below.
Here are some references so that you can learn more about how this works:
MDN page on the Object.keys() method
Accessing JavaScript
object properties: Bracket notation vs. Dot notation
And here's the working example:
const activeItem = [
{
"dnd": {
"index": 0,
"active": true,
"group":"common",
"label":"Text (000)",
"type":"text",
"icon":"text_fields",
"fontSet":"material-icons",
"class":""
},
"json": {
"schema": {
"properties": {
"text000":{
"title":"Text (000)",
"type":"string"
}
},
"required":["text000"]
},
"layout":[
{
"key":"text000",
"description":"",
"floatLabel":"auto",
"validationMessages": {
"required":"Required"
}
}
]
}
}
]
// This is the dirty looking version:
const logPropertiesDirty = activeItem[0].json.schema.properties[Object.keys(activeItem[0].json.schema.properties)[0]]
console.log("First, the dirty version where we don't save anything to variables. Everything is laid out here.")
console.log('WHAT WE DID:', 'activeItem[0].json.schema.properties[Object.keys(activeItem[0].json.schema.properties)[0]]')
console.log('RESULT:', logPropertiesDirty)
console.log('=================================================')
// This is the cleaner version, using variables to store things as we go:
const properties = activeItem[0].json.schema.properties;
const propertiesKeys = Object.keys(properties);
const propertiesKeysFirstVal = Object.keys(properties)[0];
const logPropertiesClean = properties[propertiesKeysFirstVal];
console.log('Now, the cleaner version. We save some values to variables to make things more readable.')
console.log('PROPERTIES OBJECT:', properties)
console.log('PROPERTIES KEYS:', propertiesKeys)
console.log('NAME OF FIRST PROPERTIES KEY:', propertiesKeysFirstVal)
console.log('RESULT:', logPropertiesClean)
Regarding what to call these things, I've always thought of Objects as generally consisting of "key-value pairs". Keys can also be called properties and values can also be called contents (I guess).
myObject = {
key1: value1,
property2: contentsOfProperty2
}
At the end of the day, clear communication is all that counts! So, whatever names you come up with (as long as they make reasonable sense), I'm sure people won't be jerks about it unless they feel like they have something to prove.
You should be able to use Object.values over this.activeItem.json.schema.properties:
The Object.values() method returns an array of a given object's own enumerable property values, in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).
const object1 = {
a: 'somestring',
b: 42,
c: false
};
console.log(Object.values(object1));
// expected output: Array ["somestring", 42, false]
It is not supported across the map yet, but you should be able to load a polyfill if you need it.

Compare object property to variable in localstorage in JavaScript

Is it possible to compare an object property to a variable stored in localstorage using Javascript or Jquery? Here's what I mean...
So I have an object like this:
var persons = [
{
"firstName": "Dwight",
"surName": "Stender",
"picture": "https://randomuser.me/api/portraits/med/men/99.jpg",
"id": "1"
}
]
And I have a variable stored in localstorage (the name is clickId). Now I want to compare the id from the object to that variable in localstorge. I can print them both to the console so I know they work. But when I try to compare them, it suddenly doesn't work anymore (even though the id and the variable contain the same number). This is how I compared the two:
for (i = 0; i < persons.length; i++) {
if (persons[i].id == localStorage.clickId) {
document.getElementById("result").innerHTML = "yay"
} else {
document.getElementById("result").innerHTML = "nay"
};
};
Note 1 I have also tried comparing the two with === instead of ==
Note 2 the statements to be executed inside the if...else are just placeholders for the purpose of explanation
You need to use localStorage.getItem(key) to retrieve the object you previously stored. Also note that as localStorage can only hold string you'd need to serialise the object before/after saving it. JSON would be ideal for this:
Also note that you can use some() to negate the for loop, and a ternary to simplify the if.
var persons = [{
"firstName": "Dwight",
"surName": "Stender",
"picture": "https://randomuser.me/api/portraits/med/men/99.jpg",
"id": "1"
}];
var person = JSON.parse(localStorage.getItem('person') || '{}');
document.getElementById("result").innerHTML = persons.some(p => p.id == person.clickId) ? "yay" : 'nay';
localStorage.setItem('person', JSON.stringify({
clickId: 1
}));
<div id="result"></div>
Working example
you can use the inArray method of Jquery without need to use the loop
$.inArray(value, array)
Returns index of value in array. Returns - 1 if the array does not contain the value

Checking word validity via a dictionary object in JavaScript - Is there a better way to reference/structure the dictionary?

I'm checking whether a word is real or not by referencing an object that looks like this:
dictionary.js
var dictionary = {
"apple" : "apple",
"banana" : "banana",
"orange" : "orange"
}
In JavaScript, because of the keys, the checking is "instant" (I forget the name of the lower-level phenomena in data storage that makes this possible) (hash table), rather than looping through the whole object to find a match:
if (dictionary["apple"]){
//word is valid
}
But what bothers me about this is that each word is listed twice, when the value of each property's key is never used. The property's key (name) is the only thing checked, with the value being redundant. This bothers me because for one thing, redundancy in programming looks very bad, and also this dictionary array holds over 100,000 words, and this object which must be loaded to the page (page load time) and then stored in memory (RAM being utilized) as an object is twice the necessary size.
My first idea is to just remove the values:
var dictionary = {
"apple" : "",
"banana" : "",
"orange" : ""
}
But that looks weird. So, my question is:
Is there a better way to do this?
You may want to try this:
function Dictionary()
{
this.apple =
this.banana =
this.orange = true;
}
var dictionary = new Dictionary();
console.log(dictionary.apple);
console.log(dictionary['banana']);
console.log(dictionary['not an orange'])
console.log(dictionary.notaword);
You could get a little leaner with
var dictionary = {
"apple" : true,
"banana" : true,
"orange" : true
}

Categories

Resources