This question already has answers here:
JSON dot notation to string
(3 answers)
Closed 9 years ago.
I am converting JSON data into a list structure, and I want to save the "AAA.BBB[0].CCC.DDD[5].EEE" format as the id so when a user modifies the content of that list item it modifies the JSON data associated with that location.
For Example AAA.BBB[0].CCC.DDD[5].EEE = 123
123 is a list item but I want the id to be saved as "AAA.BBB[0].CCC.DDD[5].EEE"
Would there be a better way to save the location in the id?
*Edit:
Sample Code:
JSON DATA: {"AAA":{"AAB":"Value1","AAC":"Value2","AAD":1,"AAE":"Value3","AAF":"{"ABC": "Value4"}}}
Soo the id for list item "Value4" would be AAA.AAF.ABC
function nodeIT(obj,output){
for (var x in obj){
if(!(obj[x] instanceof Object)){
//var str =JSON.stringify(obj); // Where im stuck!
output +="<li id='"+str+x +"'>";
output += (x + "=" + obj[x] + "<br />");
output +="</li>";
}
else if((obj[x] instanceof Object)){
var obj1 = obj[x];
output+="<li>" +x + "<ul>";
output=nodeIT(obj1,output);
}
}
output += "</ul></li>";
return output;
}
Instead of using the ID attribute and being forced to use a single string, you could take advantage of jQuery's .data() method, which lets you associate javascript objects with html elements.
So you do something like this when you're building the list elements:
var liElement = $('<li />')
.text(x + "=" + obj[x])
.data({
container: obj,
key: x
});
And then access the data later like this (where this refers to an li):
var container = $(this).data('container');
var key = $(this).data('key');
var value = container[key];
// .. modify value
container[key] = value;
Please see a full example here: http://jsfiddle.net/h38Ec/
Related
I am trying to iterate through an array of objects and populate an HTML select element with options whose values are the entire contents of each object. The population is successful, but the objects are turned into strings in the process and I do not know how to turn them back into objects.
Running them through JSON.parse() gives me "Uncaught SyntaxError: Unexpected token o in JSON at position 1 at JSON.parse." My research suggests that this happens when you use JSON.parse() on something that is already an object, but running typeOf() on the data beforehand reveals that it is a string.
I do not get this error if I instead run the data through JSON.parse(JSON.stringify(data)), but its output remains a string.
Please help me understand what I am misapprehending about JSON.parse(). Thank you.
const selectors = document.getElementsByClassName("ingredientSelector");
const cookButton = document.getElementById("cookButton");
//very large array of ingredient objects
let selectorOptions = "<option value = 'Nothing'>Nothing</option>";
for (let i = 0; i < ingredients.length; i++){
selectorOptions += ("<option value = '" + ingredients[i] + "'>" + ingredients[i].name + "</option>");
}
Array.prototype.forEach.call(selectors,function(selector){
selector.innerHTML = selectorOptions;
});
function cook(ingredients){
console.log("Cooking with ingredients: " + ingredients);
}
cookButton.addEventListener("click", function(){
let ingredients = [];
Array.prototype.forEach.call(selectors,function(selector){
if(selector.value !== 'Nothing'){
console.log(typeof(selector.value))
JSON.parse(selector.value);
let JSONString = JSON.stringify(selector.value);
console.log(typeof(JSONString));
let JSONObject = (JSON.parse(JSONString));
console.log(typeof(JSONObject));
console.log(JSONObject.name);
}
console.log(ingredients);
cook(ingredients);
});
});
The issue is how you're building the value properties for the options you're inserting into each selector. On this line:
selectorOptions += ("<option value = '" + ingredients[i] + "'>" + ingredients[i].name + "</option>");
Your comment says that ingredients is an array of objects, so ingredients[i] will be an object. Concatenating an object to a string will, by default, turn it into [object Object] - and this is what's causing your error. You're ending up with an option that looks something like this, perhaps:
<option value = '[object Object]'>Raw Prime Meat<object>
There's two perfectly valid approaches here. You can either store the ingredient index in the option values, which you can then use to lookup the ingredient from your master array later, or you should use JSON.stringify(ingredients[i]) to turn the object into a JSON.parseable string to make your code work as-is.
So this would work fine:
selectorOptions += ("<option value = '" + JSON.stringify(ingredients[i]) + "'>" + ingredients[i].name + "</option>");
Hello guys I've web page which have a lot of scripts, I need to get one by it's name. for e.g 'data'. I need to convert data from this script to one string.
Script is the following:
<script>data = [{'Id': '12344567', 'name': 'TestName','Amount': '1066.00', 'NumberTax': '34.00','tranasactionNumber':'139', 'otherInfo': [{'sku': 'ET|Adult','name': 'Test','category': 'Normal','price': '1032.0', 'quantity':'3'}]}];</script>
This data has array with some elements and another array inside.
Using my script I can only get info and create string with String elements from my data, but how can I get elements from inner array?
var json = '[{';
for (var i in data[0]) {
console.log('type of data[0][i] = ' + typeof data[0][i]);
if (typeof data[0][i] === 'string') {
json = json + '\'' + i + '\'' + ': ' + '\'' + data[0][i] + '\', ';
console.log(i);
console.log(data[0][i])
} else {
//Get infro from inner array
}
}
json = json + '}]';
console.log(json);
Try JSON.stringify(data) to convert object to string instead of your function.
To access the object inside the array you can use the following code:
var obj = data[0]['otherInfo'][0];
You can then use the same code you have above to loop over it and append its elements. If I understand correctly that if what you wish to do.
I think Im misunderstanding something here - I normally work in PHP and think I'm missing something small. My final array tmp is empty and displays as ",,,,,,,,,,,,,,,,". It seems to me my tmp array might be emptied somewhere or the scope gets reset for some reason. I'm using this as coordinates from a table where you can select table rows and posting to a webservice but my array seem to be erroneous.
var length = $("#arrayCount").html();
var letters = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
var col = getSelectedColumn(); //for example sake lets say "B" is the selected column
var row = getSelectedRow(); //selected rows will be from "11" - "16"
var columnIndexStart = letters.indexOf(col[0]);
var tmp = [];
for(var i = row[0]; i <= row[1]; i++) //rows[0] = 11 and rows[1] = 16
{
tmp[i] = [];
for(var j = columnIndexStart; j < letters.length; j++) //columns and starts at index 1 if we work with "B"
{
var val = $("#" + i + "_" + letters[j]).html(); //using the row and letters as the associated DOM elements ID. Easier to retrieve it's HTML then.
if(val != undefined)
{
console.log("Index [" + i + "]['" + letters[j] + "'] = " + val); //works perfectly and prints as it should.
tmp[i]['"'+letters[j]+'"'] = val; //using quotes to save letters? Is this preferred?
}
}
}
console.log('Final Array: ' + tmp); //empty??
console.log('Final Array: ' + tmp[14]['G']); //testing HTML output. But is undefined.
return tmp;
Any help will be greatly appreciated.
Edited:
Example of console output.
My final array tmp is empty and displays as ",,,,,,,,,,,,,,,,"
With non-numeric index you are setting the field of object and not the element for index.
If you will have two-dimensional numeric array with numeric indices like the following:
var tmp = [[1,2,3], [1,2,3]];
after console.log('tmp = ' + tmp); you will obviously get the output string like:
tmp = 1,2,3,1,2,3
Because when you are trying to convert array to string it converts it elements to string and represent them with a commas.
However when you are trying to set element with non-numeric index, you are setting the field of this object.
var tmp = [];
tmp['A'] = 123;
console.log("tmp = " + tmp); // tmp =
console.log(tmp.A); //123
So, console.log in your case works good - it is serializing all elements of two-dimensional array. But no one array of the second level does not have stored values, it has only fields, which are not included in the string representation of array.
You are getting a set of commas, because each sub-array of tmp array does not contains any element, so it's string representation is an empty string. Each sub-array contains the required data into it's fields.
When you are performing sum operation of string and object you are forcing object to convert to string representation. Instead of this it is recommended to use console.log(yourObj) - it will log the whole object without converting it to string.
//using quotes to save letters? Is this preferred?
No, "A" and A are different identifiers.
var s = new Object();
s['"A"'] = 123;
console.log(s['A']); //undefined
console.log(s['"A"']); //123
Additionally, if you will set fields with quotes - you can not get the field in normal style:
console.log(s."A"); //syntax error : expected identifier after '.'
You can also just do this (use comma, not plus):
console.log('Final Array: ', tmp); //empty??
console.log('Final Array: ', tmp[14]['G']);
Hi I have a script which parses a local JSON object (at the moment just to display a list).
function generateFamilySelect() {
var implantData = JSON.parse(localStorage.getItem("implantData"));
var implantFamilies = "";
$.each(implantData.implantFamilies, function( index, value ) {
implantFamilies += implantData.implantFamilies[index].familyDisplay + "<br />";
});
$("#holderForFamilySelect").html(implantFamilies);
}
and the JSON object:
{"implantFamilies":[
{"id":"1","familySelector":"aa","familyDisplay":"One","loadInitially":"1"},
{"id":"2","familySelector":"bb","familyDisplay":"Two","loadInitially":"1"},
{"id":"3","familySelector":"cc","familyDisplay":"Three","loadInitially":"1"},
{"id":"4","familySelector":"dd","familyDisplay":"Four","loadInitially":"0"},
{"id":"5","familySelector":"ee","familyDisplay":"Five","loadInitially":"0"},
{"id":"6","famiā¦
At the moment, the list shows all of the elements. How can I modify this script to only show those with "loadInitially":"1"?
Also, a quick syntax question, I feel like the line
implantFamilies += implantData.implantFamilies[index].familyDisplay + "<br />";
could be written something like
implantFamilies += this[index].familyDisplay + "<br />";
but I can't get that to work...
The easiest is to use the Javascript Array.filter() method
// (or in your case, you get it from localstorage, but here's the data)
var myJson = {"implantFamilies":[
{"id":"1","familySelector":"aa","familyDisplay":"One","loadInitially":"1"},
{"id":"2","familySelector":"bb","familyDisplay":"Two","loadInitially":"1"},
{"id":"3","familySelector":"cc","familyDisplay":"Three","loadInitially":"1"},
{"id":"4","familySelector":"dd","familyDisplay":"Four","loadInitially":"0"},
{"id":"5","familySelector":"ee","familyDisplay":"Five","loadInitially":"0"}] };
//the array of implant families
var implantFamilies = myJson.implantFamilies;
//the filtering function. This is preferable to $.each
function implantFamiliesThatLoadInitially(implantFamily){
return implantFamily.loadInitially === '1';
}
//this is only the ones you want, (filtered by loadInitially property)
var loadInitiallyImplantFamilies = implantFamilies.filter(implantFamiliesThatLoadInitially);
The goal of the second part of your code is to build some html based on the data in the json, stored in teh variable implantFamilies. I will recommend Array.map() as an easier solution, than dealing with this. like before I am breaking this into multiple steps with comments so it is clear what is happening.
//your map function. You can make any html you want, like li's
function toImplantFamilyHtml(family){
return family.familyDisplay + '<br />'
}
//returns a plain string of html
var implantFamilyHtml = loadInitiallyImplantFamilies.map(toImplantFamilyHtml);
//jquery object you can use, or append to the DOM or whatever
var $implantFamilyHtml = $(implantFamilyHtml);
//append to DOM
$("#holderForFamilySelect").html($implantFamilyHtml);
working Fiddle: https://jsfiddle.net/mv850pxo/2/
the_5imian has provided a good answer to your first question, and you have determined the obvious alternate solution, given your current code.
As to your second question (this within jQuery.each()):
Within jQuery.each(), this is the value wrapped as an Object. value is the value of the array element at the current index, not the entire array. In other words, you don't use [index] on value or this within this context to get the current array element. For this code, value and this are the same because value is already an Object.
For what you want, you could just use value (Given that all elements of the array are already Objects, you could use this instead, but using value is a better habit to be in.):
$.each(implantData.implantFamilies, function( index, value ) {
if (value.loadInitially == "1") {
implantFamilies += value.familyDisplay + "<br />";
} else {
//do nothing
}
});
this is the value wrapped as an Object:
The following should show you what the values of value and this are within $.each(array,function(index,value){...});:
var myArray = ['zero','one','two','three','four','five'];
$.each(myArray, function(index,value){
console.log(index + ' value =',value);
console.log(index + ' this =',this); //this is the value wrapped as an Object.
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Well that just seems obvious now.
$.each(implantData.implantFamilies, function( index, value ) {
if (implantData.implantFamilies[index].loadInitially == "1") {
implantFamilies += implantData.implantFamilies[index].familyDisplay + "<br />";
} else {
//do nothing
}
});
How about the second part of my question?
This question already has answers here:
How to loop through a plain JavaScript object with the objects as members
(28 answers)
Closed 8 years ago.
How can I list the structured contents of a Javascript Object in HTML?
My object looks like this:
var lists = {
"Cars":{"Ford":false,"Ferarri":false},
"Names":{"John":true,"Harry":false},
"Homework":{"Maths":true,"Science":false,"History":true,"English":true}
}
What would the loop look like to print the keys as headers, and the property + values as an ordered list underneath?
Example:
Cars
Ford = False
Ferrari = False
Names
John = True
Harry = False
Homework
Maths = True
Science = False
History = True
English = True
I understand that I can append the object by name to HTML, but if the object is dynamic, and the key isn't known, how can I make a loop to do so?
Just got to loop, create the HTML string, and append! Say you have a container:
<div id="container"></div>
And your JS
var htmlString = "";
for (var key in lists) {
htmlString += "<span>" + key + "</span>";
htmlString += "<ul>";
for (var item in lists[key]) {
htmlString += "<li>" + item + " = " + lists[key][item] + "</li>";
}
htmlString += "</ul>";
}
document.getElementById("container").innerHTML = htmlString;
Working demo: http://jsfiddle.net/owqt5obp/