Compare object property to variable in localstorage in JavaScript - 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

Related

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");

Javascript return statement inside filter function, get uniques. Why code works?

I have a big array of objects where I need to get the unique values for some keys.
I have the code working, but I would like to understand it.
Object
{
"cor": {
"id": 89,
"code": "192"
},
"tamanho": {
"id": 74,
"code": "L"
},
"price": "56,34",
"prevPrice": "93,90",
"stock": 0
}
And this is the iteration that return only unique values.
What I can't understand is the return statement, how does javasacript reads it?
var tamanhos = [];
data.grelha.filter(function(el, i, arr) {
return tamanhos.indexOf(el.tamanho.id) == -1 && tamanhos.push(el.tamanho.id);
});
Thanks a lot!
Before I get to what I think you're asking, let's talk about .filter(). Firstly, it returns a new array, so calling .filter() without using its return value is not how you are supposed to use it: if you just want to iterate over the array you should use .forEach() instead. It works by calling the function you pass it once per array element. Only elements for which your function returns a truthy value will be added to the output array. The correct way to use .filter() to solve this problem would be something like this:
var tamanhos = data.grelha.map(el) { return el.tamaho.id }).filter(function(el, i, arr) {
return arr.indexOf(el) === i
})
That is, first use .map() to get a list of all the IDs, then use .filter() to only keep elements if they are the first occurrence of that ID in the array, thus setting tamanhos to be an array of unique IDs.
Now to what you seem to be asking, which is for an explanation of what the following line is doing:
return tamanhos.indexOf(el.tamanho.id) == -1 && tamanhos.push(el.tamanho.id);
The key is the && (logical AND) operator. It uses short circuit evaluation, which means that the expression on the right-hand-side of the && will only be evaluated if the expression on the left-hand-side is truthy.
Two simple examples (click "Run"):
true && alert('This WILL display because alert() is called.');
false && alert('This will NOT display because alert() is not called');
So if tamanhos.indexOf(el.tamanho.id) == -1 is true then the tamanhos.push(el.tamanho.id) part will be executed, otherwise the .push() will not be executed. In other words, the part after the return is equivalent to doing this:
if (tamanhos.indexOf(el.tamanho.id) == -1) {
tamanhos.push(el.tamanho.id);
}
(That is, if the item isn't already in the tamanhos array then add it.)
The result of the whole && expression is then returned, but as mentioned above that is not really relevant because you don't use the return value from .filter(). So what your code is doing is equivalent to this:
var tamanhos = [];
data.grelha.forEach(function(el) {
if (tamanhos.indexOf(el.tamanho.id) == -1) {
tamanhos.push(el.tamanho.id);
}
});
this is a json datas. Json values can use array. I think, you know arrays. So Arrays has multi areas. Like :
[val1]
[val1, val2]
[val1, val2, val3]
[val1, val2, val3, .....]
we can take values as column name. Example for c#:
array[] names = new array["mesut", "joa"]
you have javascript arrays

Json parent value with nested children

I want to create a Json object (in javascript) with multible childeren. But the parent must also have a value, so the code can be executed as:
var parent = {
"child": {
"ownValue": "valueChild",
"grandchild": "ValueGrandChild",
}
};
parent.child.grandchild // return "valueGrandChild"
parent.child // return "valueChild"
Is this possible in javascript?
If I understand your question (I'm not sure), I would use a different strategy to solve your problem.
As you know, json objects does not have attributes but just children properties. You can use a properties called child to store the children objects (the subtree) of your parent object.
var parent = {
"value": "Parent own value",
"child": {
"grandchild": {"value": "ValueGrandChild", "child": {}}
"anotherchild": {"value": "anotherChildValue", "child": {}}
}
};
Children and attributes are better separated and you can address them (and the "proper" object properties) as below:
parent.child.grandchild.value // returns "valueGrandChild"
parent.value // returns "Parent own value"
You can have also some other commodities:
var how_many_child = Object.keys(parent.child).length
var a_child = parent.child.anotherchild
var how_many_nephew = Object.keys(a_child.child).length
a_chid.value; // returns "anotherChildValue"
parent.child.anotherchild.value; // returns "anotherChildValue"
Not sure if I understand the question, but you have an error in your formatting of the object at least. It works the way you want if you change the ";" to a ",". (Look below)
Change it from;
var parent = {
"child": {
"ownValue": "valueChild";
"grandchild": "ValueGrandChild";
}
};
to;
var parent = {
"child": {
"ownValue": "valueChild",
"grandchild": "ValueGrandChild",
}
};
That was you can get the valueChild by using;
parent.child.ownValue
Even if you did get an object to return another value, you would no longer be able to use that object normally. Every reference to the object would only be referencing the value (invalidating nested object references). You could obviously just keep the "ownValue" property to use for each value you want to tie to an object though.

find if path exists in json nodejs

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/

How come I can't lookup associated array like this?

urlMap = {
'0': {'6b4247404960fd4e418d242f3b7f0412': 'http://google.com', '123':'http://ibm.com'},
'1': {'4c27ffaef99b7a6dbe838b46bcc09779' : 'http://yahoo.com', '456':'http://abc.com'}
};
$(function() {
var l = new Array(1,2,3,4);
for (var i = 0; i < l.length; i++){
$("#"+i.toString()+".foo").change(function() {
g = i.toString();
window.location.href = urlMap[g][$(this).val()];
})}});
I tried to use urlMap[i] it won't work. When I hardcode urlMap['0'] it works.
From Firebug, I see this
urlMap[g] is undefined
[Break On This Error]
window.location.href = urlMap[g][$(this).val()];
How am I suppose to lookup the dictionary?
Thanks.
It's very hard to tell what you're trying to do. You have a map that has two entries, with the keys "0" and "1", but you have a loop that's looping through the values 0, 1, 2, and 3, and then using those values to look up things in the map.
There are at least three problems with the quoted code:
You're trying to access the keys "0", "1", "2", and "3" of an object that only has the keys "0" and "1".
You're creating a function in a loop that's a closure over the variable i, and so will only see the value of i as of later, then the closure is called. This is because closures receive a live reference to the variable, not a copy of its value when they're created. So all of your click handler functions will try to use the key "4" (the value of i after the loop completes), which doesn't exist in your map.
You're not declaring g anywhere, and so falling prey to The Horror of Implicit Globals.
Here's my best guess at what you're actually trying to do:
urlMap = {
'0': {'6b4247404960fd4e418d242f3b7f0412': 'http://google.com', '123':'http://ibm.com'},
'1': {'4c27ffaef99b7a6dbe838b46bcc09779' : 'http://yahoo.com', '456':'http://abc.com'}
};
$(function() {
for (var i = 0; i < 2; i++){
$("#"+i.toString()+".foo").change(createHandler(i));
}
function createHandler(index) {
return function() {
window.location.href = urlMap[index][$(this).val()];
};
}
});
Changes:
I only try to access elements "0" and "1" of the map, since those are the only elements it has.
I use the createHandler function to ensure that the handler we create is closing over the index argument to createHandler, rather than the i value in the loop. The index argument won't change, whereas i will (as I mentioned) change as the loop continues.
I got rid of g, which we don't need, and just use index directly. Property names are always strings (even when the object is an "array"); any time you index into an object, if the index value you supply is a number, it'll get turned into a string, so you don't have to do it explicitly (though you might if you prefer).
As the error clearly states, urlMap[g] does not exist.
You need to create it first.

Categories

Resources