Selecting a JSON object by number not by name - javascript

I try to store a JSON object with informations in multiple languages. Im not even sure they way i did it is good, any suggestions are welcome.
My current problem ist, that i dont know how to access the first language without knowing what language it is.
var Data = {
"NameIntern": "Something intern",
"en": {
"Name": "Some name",
"ModuleOrder": "123,333,22" }
};
document.write(Data[1].Name);
I just want to access the second object, sometimes its "en", sometimes its "de".
Thanks for any tipps!

Here is a pure javascript solution:
First: You get the keys of the object:
var keys = Object.keys(Data);
Then: The keys are stored in a array. You can access them with an index. Like:
Data[keys[0]]
Now: You can use a foor loop or whatever you want :)

Data is an object its not array so you cant access it like Data[0] you can access it like Data.en.
but as you say you dont know any thing about en or de so i suggest that you form the Data object like this :
var Data =[{
lang:"en",
langData:{
Name:"Some name"
}
}]

var Data = {
"NameIntern": "Something intern",
"en": {
"Name": "Some name",
"ModuleOrder": "123,333,22" }
};
var index = 0;
$.each(Data, function(key, val){
index += 1;
if (index == 2){
// key is the language, like in this example key is 'en'
console.log(key);
}
});

var name = (Data.en || Data.de || {})['Name'];
(Data.en || Data.de || {}) get's value of Data.en or Data.de if both doesn't exist, return empty object, so that script doesn't throw exception for Name property
()['Name'] same as myObject['Name'], myObject.Name
assign value to name variable, it will be Some name or undefined at least
If you have more languages, add them all, notice: it will return first found lang
var name = (Data.en || Data.de || Data.ru || Data.fr || {})['Name'];

Use Object.keys method to get list of object property names:
console.log(Data[Object.keys(Data)[1]]['Name']); // "Some name"

Related

localStorage.removeItem() not removing key/value from object

Struggling to figure this one out...
I'm trying to remove a key/value pair, from my localStorage object. However, nothing gets removed. (I also don't have any errors).
I understand I can remove the key/value in question, by it's key name. Here's an example of the object:
bookMarksArray: [
{
"name": "reena",
"url": "brian"
},
{
"name": "joe",
"url": "ault"
}
]
And here's my code... I'm using event target to grab and match the key name, to the object index.
And then passing in key of that object index, into localStorage.removeItem()... What am I doing wrong?
list.addEventListener('click', event => {
if (event.target.classList.contains('js-delete-url')) {
const editName = event.target.parentElement.name.value;
const objIndex = bookMarksArray.findIndex(obj => obj.name === editName);
localStorage.removeItem(bookMarksArray[objIndex].name);
console.log('delete', bookMarksArray[objIndex].name);
}
});
Console prints this:
app.js:55 delete reena
Thank you!
LocalStoage saves the value in string format, so you have to stringify JSON object every time to save it in localStorage, we can solve this problem, please find below code snippet, useful in this scenario,
var updateStorage = function(filterName) {
var bookMarksArray= [{"name": "reena", "url": "brian"}, {"name": "joe", "url": "ault"}]
localStorage.setItem('nameList', JSON.stringify(bookMarksArray));
var items = JSON.parse(localStorage.getItem('nameList'));
var updatedList = items.filter(function(a) {
return a.name !== filterName;
});
localStorage.setItem('nameList', JSON.stringify(updatedList));
console.log(localStorage.getItem('nameList'));
// result [{"name":"reena","url":"brian"}]
};
updateStorage('joe');
//set js object to localstorage
localStorage.setItem('bookMarksArray',JSON.stringify(bookMarksArray))
//get js object from localstorage
bookMarksArray= JSON.parse(localStorage.getItem('bookMarksArray'))
//remove desired item
bookMarksArray = bookMarksArray.filter(function(item) {
return item.name !== 'reena';
});
//update js object in localstorage
localStorage.setItem('bookMarksArray',JSON.stringify(bookMarksArray))

How can I reformat this simple JSON so it doesn't catch "Circular structure to JSON" exception?

Introduction
I'm learning JavaScript on my own and JSON its something along the path. I'm working on a JavaScript WebScraper and I want, for now, load my results in JSON format.
I know I can use data base, server-client stuff, etc to work with data. But I want to take this approach as learning JSON and how to parse/create/format it's my main goal for today.
Explaining variables
As you may have guessed the data stored in the fore mentioned variables comes from an html file. So an example of the content in:
users[] -> "Egypt"
GDP[] -> "<td> $2,971</td>"
Regions[] -> "<td> Egypt </td>"
Align[] -> "<td> Eastern Bloc </td>"
Code
let countries = [];
for(let i = 0; i < users.length; i++)
{
countries.push( {
'country' : [{
'name' : users[i],
'GDP' : GDP[i],
'Region' : regions[i],
'Align' : align[i]
}]})
};
let obj_data = JSON.stringify(countries, null, 2);
fs.writeFileSync('countryballs.json', obj_data);
Code explanation
I have previously loaded into arrays (users, GDP, regionsm align) those store the data (String format) I had extracted from a website.
My idea was to then "dump" it into an object with which the stringify() function format would format it into JSON.
I have tested it without the loop (static data just for testing) and it works.
Type of error
let obj_data = JSON.stringify(countries, null, 2);
^
TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Node'
| property 'children' -> object with constructor 'Array'
| index 0 -> object with constructor 'Node'
--- property 'parent' closes the circle
What I want from this question
I want to know what makes this JSON format "Circular" and how to make this code work for my goals.
Notes
I am working with Node.js and Visual Studio Code
EDIT
This is further explanation for those who were interested and thought it was not a good question.
Test code that works
let countries;
console.log(users.length)
for(let i = 0; i < users.length; i++)
{
countries = {
country : [
{
"name" : 'CountryTest'
}
]
}
};
let obj_data = JSON.stringify(countries, null, 2);
fs.writeFileSync('countryballs.json', obj_data);
});
Notice in comparison to the previous code, right now I am inputing "manually" the name of the country object.
This way absolutely works as you can see below:
Now, if I change 'CountryTest' to into a users[i] where I store country names (Forget about why countries are tagged users, it is out of the scope of this question)
It shows me the previous circular error.
A "Partial Solution" for this was to add +"" which, as I said, partially solved the problem as now there is not "Circular Error"
Example:
for(let i = 0; i < users.length; i++)
{
countries = {
country : [
{
"name" : users[i]+''
}
]
}
};
Resulting in:
Another bug, which I do not know why is that only shows 1 country when there are 32 in the array users[]
This makes me think that the answers provided are not correct so far.
Desired JSON format
{
"countries": {
"country": [
{
"name": "",
"GDP" : "",
"Region" : "",
"Align" : ""
},
{
"name": "",
"GDP" : "",
"Region" : "",
"Align" : ""
},
{
"name": "",
"GDP" : "",
"Region" : "",
"Align" : ""
}
]}
}
Circular structure error occurs when you have a property of the object which is the object itself directly (a -> a) or indirectly (a -> b -> a).
To avoid the error message, tell JSON.stringify what to do when it encounters a circular reference. For example, if you have a person pointing to another person ("parent"), which may (or may not) point to the original person, do the following:
JSON.stringify( that.person, function( key, value) {
if( key == 'parent') { return value.id;}
else {return value;}
})
The second parameter to stringify is a filter function. Here it simply converts the referred object to its ID, but you are free to do whatever you like to break the circular reference.
You can test the above code with the following:
function Person( params) {
this.id = params['id'];
this.name = params['name'];
this.father = null;
this.fingers = [];
// etc.
}
var me = new Person({ id: 1, name: 'Luke'});
var him = new Person( { id:2, name: 'Darth Vader'});
me.father = him;
JSON.stringify(me); // so far so good
him.father = me; // time travel assumed :-)
JSON.stringify(me); // "TypeError: Converting circular structure to JSON"
// But this should do the job:
JSON.stringify(me, function( key, value) {
if(key == 'father') {
return value.id;
} else {
return value;
};
})
The answer is from StackOverflow question,
Stringify (convert to JSON) a JavaScript object with circular reference
From your output, it looks as though users is a list of DOM nodes. Rather than referring to these directly (where there are all sort of possible cyclical structures), if you just want their text, instead of using users directly, try something like
country : [
{
"name" : users[i].textContent // maybe also followed by `.trim()
}
]
Or you could do this up front to your whole list:
const usersText = [...users].map(node => node.textContent)
and then use usersText in place of users as you build your object.
If GDP, regions and align are also references to your HTML, then you might have to do the same with them.
EUREKA!
As some of you have mentioned above, let me tell you it is not a problem of circularity, at first..., in the JSON design. It is an error of the data itself.
When I scraped the data it came in html format i.e <td>whatever</td>, I did not care about that as I could simply take it away later. I was way too focused in having the JSON well formatted and learning.
As #VLAZ and #Scott Sauyezt mentioned above, it could be that some of the data, if it is not well formatted into string, it might be referring to itself somehow as so I started to work on that.
Lets have a look at this assumption...
To extract the data I used the cheerio.js which gives you a kind of jquery thing to parse html.
To extract the name of the country I used:
nullTest = ($('table').eq(2).find('tr').eq(i).find('td').find('a').last());
//"Partial solution" for the OutOfIndex nulls
if (nullTest != null)
{
users.push(nullTest);
}
(nullTest helps me avoid nulls, I will implement some RegEx when everything works to polish the code a bit)
This "query" would output me something like:
whatEverIsInHereIfThereIsAny
or else.
to get rid off this html thing just add .html() at the end of the "jquery" such as:
($('table').eq(2).find('tr').eq(i).find('td').find('a').last().html());
That way you are now working with String and avoiding any error and thus solves this question.

JAVASCRIPT object to array conversion

I search on stackoverflow before post my question, but I didn't find any solution. I have an object like this :
"{"COURRIERS":
{"05. Juridique":
[{"res_id":100,"type_label":"Plainte","subject":"test23","doctypes_first_level_label":"COURRIERS","doctypes_second_level_label":"05. Juridique","folder_level":2}]
}
}"
And I need to access it like an array, in order to get the information like res_id etc..
How can I do this ?
Thanks in advance
Assuming that you won't have more than one object/array in each layer, this should get you what you need.
let obj = {
"COURRIERS": {
"05. Juridique": [{
"res_id": 100,
"type_label": "Plainte",
"subject": "test23",
"doctypes_first_level_label": "COURRIERS",
"doctypes_second_level_label": "05. Juridique",
"folder_level": 2
}]
}
}
let folder = Object.keys(obj)[0]
let type = Object.keys(obj[folder])[0]
let result = obj[folder][type][0]
console.log(result)
You can gain access to the data in multiple ways. The following below will help clarify some of the way you can access some of the data.
myObj.type = "Dot syntax";
myObj.type = "Dot syntax";
myObj["date created"] = "String with space";
myObj[str] = "String value";
myObj[rand] = "Random Number";
myObj[obj] = "Object";
myObj[""] = "Even an empty string";
For your problem you can use the following
var x = {
"COURRIERS":{
"05. Juridique":[
{
"res_id":100,
"type_label":"Plainte",
"subject":"test23",
"doctypes_first_level_label":"COURRIERS",
"doctypes_second_level_label":"05. Juridique",
"folder_level":2
}
]
}};
console.log(x['COURRIERS']['05. Juridique'][0].res_id)
Something like that ?
(I insert the data inside a variable and print the wanted result with key index)
let obj = {
"COURRIERS":{
"05. Juridique":[
{
"res_id":100,
"type_label":"Plainte",
"subject":"test23",
"doctypes_first_level_label":"COURRIERS",
"doctypes_second_level_label":"05. Juridique",
"folder_level":2
}
]
}
};
console.log(obj["COURRIERS"]["05. Juridique"][0]["res_id"]);
EDIT
You want to acess it with variable.
For avoid bug, I strong recommend you to check if the variable value key exist in the array/object like :
let folder = 'COURRIERS';
if(folder.indexOf(data) >= 0) { // folder.indexOf(data) = 0
// ... finish the job here :)
}
// indexOf return -1 if the value is not found

How to delete a key within an object in local storage with Javascript and/or Jquery?

In local storage I have an object named favourites and it contains this..
"{
"id3333":{
"URL":"somewhere.comm/page1/",
"TITLE":"Page 1 Title",
},
"id4444":{
"URL":"somewhere.comm/page2/",
"TITLE":"Page 2 Title",
}
}"
How can I delete an object based on its ID (id3333 & id4444 for examples)
I have tried the following along with some other voodoo..
localStorage.removeItem('id3333'); // no errors, no removal
localStorage.removeItem('favourites':'id3333'); // SyntaxError: missing ) after argument list
localStorage.removeItem('favourites[id3333]'); // no errors, no removal
localStorage.removeItem('id3333', JSON.stringify('id3333')); // no errors, no removal
Also, I will need to get the key name to delete based on a variable, so like this..
var postID = 'id3333';
localStorage.removeItem(postID);
or
var objectName = 'favourites';
var postID = 'id3333';
localStorage.removeItem(objectName[postID]);
Is it possible to remove a nested item directly or do I need to retrieve the full object and then delete the item and then set the object back to local storage again?
The closest I can get to deleting anything directly so far is..
localStorage.removeItem('favourites');
But that of course removes the entire object.
You have a a single key and you are acting like there are multiple keys
var obj = {
"id3333":{
"URL":"somewhere.comm/page1/",
"TITLE":"Page 1 Title",
},
"id4444":{
"URL":"somewhere.comm/page2/",
"TITLE":"Page 2 Title",
}
};
window.localStorage.favs = JSON.stringify(obj); //store object to local storage
console.log("before : ", window.localStorage.favs); //display it
var favs = JSON.parse(window.localStorage.favs || {}); //read and convert to object
var delKey = "id3333"; //key to remove
if (favs[delKey]) { //check if key exists
delete favs[delKey]; //remove the key from object
}
window.localStorage.favs = JSON.stringify(favs); //save it back
console.log("after : ", window.localStorage.favs); //display object with item removed
With localStorage.removeItem you can only remove top level keys, i.e. keys directly on localStorage.
Because id3333 is on localStorage.favourites you cannot remove it using localStorage.removeItem.
Instead try delete localStorage.favourties['id3333']
Simple, actually: you just delete it. :)
x = {
"id3333":{
"URL":"somewhere.comm/page1/",
"TITLE":"Page 1 Title",
},
"id4444":{
"URL":"somewhere.comm/page2/",
"TITLE":"Page 2 Title",
}
};
console.log(x);
delete x.id3333;
console.log(x);
delete does what you're looking for. You could also do something like delete x.id3333.TITLE if you were so inclined. Note also that delete returns true if successful and false if not.
Suppose you set a nested object in localStorage like that
const dataObj = {
uid: {
name: 'robin',
age: 24,
}
}
window.localStorage.setItem('users', JSON.stringify(dataObj));
Now you want to delete the age property. You can't remove it with removeItem native function since it allows to delete from top level.
So you need to get the data first and delete the property you want and set the data again to localStorage with updated value like that
const existingLocalStorage = JSON.parse(window.localStorage.getItem('users') || {});
if(existingLocalStorage['uid']['age']) { // if throws any error, use lodash get fucntion for getting value
delete existingLocalStorage['uid']['age'];
}
window.localStorage.setItem('users', JSON.stringify(existingLocalStorage));

Javascript [Object object] error in for loop while appending string

I am a novice trying to deserialize my result from an onSuccess function as :
"onResultHttpService": function (result, properties) {
var json_str = Sys.Serialization.JavaScriptSerializer.deserialize(result);
var data = [];
var categoryField = properties.PodAttributes.categoryField;
var valueField = properties.PodAttributes.valueField;
for (var i in json_str) {
var serie = new Array(json_str[i] + '.' + categoryField, json_str[i] + '.' + valueField);
data.push(serie);
}
The JSON in result looks like this:
[
{
"Text": "INDIRECT GOODS AND SERVICES",
"Spend": 577946097.51
},
{
"Text": "LOGISTICS",
"Spend": 242563225.05
}
]
As you can see i am appending the string in for loop..The reason i am doing is because the property names keep on changing therefore i cannot just write it as
var serie = new Array(json_str[i].propName, json_str[i].propValue);
I need to pass the data (array type) to bind a highchart columnchart. But the when i check the var serie it shows as
serie[0] = [object Object].Text
serie[1] = [object Object].Spend
Why do i not get the actual content getting populated inside the array?
You're getting that because json_str[i] is an object, and that's what happens when you coerce an object into a string (unless the object implements toString in a useful way, which this one clearly doesn't). You haven't shown the JSON you're deserializing...
Now that you've posted the JSON, we can see that it's an array containing two objects, each of which has a Text and Spend property. So in your loop, json_str[i].Text will refer to the Text property. If you want to retrieve that property using the name in categoryField, you can do that via json_str[i][categoryField].
I don't know what you want to end up with in serie, but if you want it to be a two-slot array where the first contains the value of the category field and the second contains the value of the spend field, then
var serie = [json_str[i][categoryField], json_str[i][valueField]];
(There's almost never a reason to use new Array, just use array literals — [...] — instead.)

Categories

Resources