JSON - searching through keys with variable names (unknown) - javascript

Total JSON noob here. I'm trying to cycle through some JSON to pull out the first image from an array inside the object, and after 4 hours of having at it, I've decided I probably need some help.
I'm able to pull every value I need out of the object where I know the key, but I have some data that has non consistent key names that I need to basically iterate through looking for a partial match and then pulling the first on of these results.
The Json structure of the unknown element is structured like this:
"custom_fields": {
"content_0_subheading": [
"Title text"
],
"content_1_text": [
"Some text"
],
"content_2_image": [
[
"http://staging.livelivelyblog.assemblo.com/wp-content/uploads/2013/09/wellbeing-260x130.jpg",
260,
130,
true
]
],
"content_2_caption": [
""
]
}
What I'm after is the content_2_image in this case, but in another entry it could be content_20_image for all I know (there's a lot of data being pulled).
Any ideas of the best way to cycle through these unknown keys looking for a partial match on '_image' in the key or something, would be VERY appreciated.
Thanks!

You can't just search through every field with a partial match, so you'll have to iterate through every field and then check the field names for the match. Try something like this:
var json = {
"content_0_subheading": [
"Title text"
],
"content_1_text": [
"Some text"
],
"content_2_image": [
[
"http://staging.livelivelyblog.assemblo.com/wp-content/uploads/2013/09/wellbeing-260x130.jpg",
260,
130,
true
]
],
"content_2_caption": [
""
]
}
for (var key in json) {
if (json.hasOwnProperty(key)) {
if (/content_[0-9]+_image/.test(key)) {
console.log('match!', json[key]); // do stuff here!
}
}
}
Basically, what we're doing is:
1) Loop through keys of json object for (var key in json)
2) Ensure the json has the property, and we're not accessing keys we don't want if (json.hasOwnProperty(key))
3) Check if key matches the regular expression /content_[0-9]+_image/
3a) Basically, test if it matches content_ANY NUMBERS_image where ANY NUMBERS is equal to at least one digit or more
4) Use that data however you please console.log(json[key])
Hope this helps!

You could use for ... in
for (key in object) {
// check match & do stuff
}

var json = JSON.parse(YOUR_JSON_STRING).custom_fields, //Fetch your JSON
image; //Pre-declare image
for(key in json){ //Search each key in your object
if(key.indexOf("image") != -1){ //If the index contains "image"
image = json[key]; //Then image is set to your image array
break; //Exit the loop
}
}
/*
image[0] //the URL
image[1] //the width
image[2] //the height
image[3] //your boolean

Related

How to remove character from left of the string until first : if found?

I have JSON String as the one below which is returned from the previous function. It is a string, not object.
{
"qs1": {
"mistake": [{
"id": 1,
"name": "Subject-Verb Agreement Errors."
}, {
"id": 1,
"name": "Sentence Fragments."
}, {
"id": 1,
"name": "Missing Comma After Introductory Element."
}]
}
}
I converted it into an object by using Jquery.parseJSON() now I want to use length to find a number of mistakes.
Problem:
the first key qs1 of the returned JSON can be different like qs2,qs3 & so on. I don't want to use a loop to get the key name qs1,qs2 because it will take a lot of time in only getting a key name and if I have a lot of questions. Also, I don't know the number of questions.
Is there is any way to check qs1.mistake.length>0 without knowing the key name(qs1).
Below is my function:
function SelectiMstake(value) {
alert(value);
var value2 = jQuery.parseJSON(value);
var NewHtml="";
if(value2.mistake.length>0) {
alert("mistake found");
//for(var mistakei = 0; mistakei < value2.mistake.length; mistakei++) {
// NewHtml+= "<input type='check' value='"+ value2.mistake[mistakei] +"'>"+ value2.mistake[mistakei] +"<br>";
// }
//$("#DisplayMistakes").html(NewHtml);
} else {
alert("No mistakes found in the following Question");
}
}
if there is no way I want to stick with my question part when I get JSON string then I want to remove {"qs1": from the start of the string and } from the last. Don't use a character to remove from the start otherwise {"qs12": this will give the wrong result.
Use Object.values(), and just select the first element, or loop through the values (Which is now an array), if you want to check each qs*:
var json = '{"qs1":{"mistake":[{"id":1,"name":"Subject-Verb Agreement Errors."},{"id":1,"name":"Sentence Fragments."},{"id":1,"name":"Missing Comma After Introductory Element."}]}}';
var parsed = JSON.parse(json);
var vals = Object.values(parsed);
console.log(vals[0]);
console.log(vals[0].mistake.length); // 3

Javascript Compare Index with Array Value

I have a main array, and an object that contains an array of items. I want to see if the object that contains items matches the main array index. If a match, then write to the console.
var mainItems = [0,1,2,3,4,5,6,7,8,9,10,"car", "boat", "truck", "plane"];
var nonStandardItems =
{
"items": [
{
"value": "8",
"code": "8ic"
},
{
"value": "boat",
"code": "10bt"
}
],
}
if( nonStandardItems.items.slice(-1)[0].value == mainItems.indexOf(nonStandardItems.items.slice(-1)[0].value) ){
console.log("you are right");
}
However, I only get a value of -1, and an error. What am I missing?
EDIT
I am pulling data from a different data sources, all containing junk data. However, the last item in the junk data array is the item I need.
I want to check if the results from my api request match an "expected" or "standard" set of data. For example, my nonStandardItems object is an example of what I get back from the api.
I want to parse it, and check to see if the LAST item in the items array has a value that matches the index of my standard items array. My junk items array contains numeric and text data, but the last item will always have either a numerical or textual code that I expect.
The example was contrived and rushed, so I apologize for the spelling, syntactical and explanation mistakes. The error the console threw was that nonstandardItems.items[-1].value did not exist.
Use filter():
if (nonStandardItems.items.filter(v => mainItems.indexOf(v.code) == v.value).length > 0) {
console.log("you are right")
}

Is there a way to iterate and display the list of key value pairs of json using Handlebar.js

As Iam new to javascript, I found handleBar.js can be used to template with dynamic data.
I worked on a sample which worked fine and the json structure was simple and straight forward.
(function()
{
var wtsource = $("#some-template").html();
var wtTemplate = Handlebars.compile(wtsource);
var data = { users: [
{url: "index.html", name: "Home" },
{url: "aboutus.html", name: "About Us"},
{url: "contact.html", name: "Contact"}
]};
Handlebars.registerHelper('iter', function(context, options) {
var fn = options.fn, inverse = options.inverse;
var ret = "";
if(context && context.length > 0) {
for(var i=0, j=context.length; i<j; i++) {
ret = ret + fn($.extend({}, context[i], { i: i, iPlus1: i + 1 }));
}
} else {
ret = inverse(this);
}
return ret;
});
var temp=wtTemplate(data);
$("#content").html(temp);
})();
<script id="some-template" type="text/x-handlebars-template">
{{#iter users}}
<li>
{{name}}
</li>
{{/iter}}
</script>
How to iterate a json with the below structure ? Please do suggest the possible way for iterating and creating the template for the below json structure
var newData = { "NEARBY_LIST": {
"100": {
"RestaurantID": 100,
"ParentRestaurantID": 0,
"RestaurantName": "Chennai Tiffin",
"listTime": [{
"startTime": "10:00",
"closeTime": "23:30"
} ]
},
"101": {
"RestaurantID": 101,
"ParentRestaurantID": 0,
"RestaurantName": "Biriyani Factory",
"listTime": [{
"startTime": "11:00",
"closeTime": "22:00"
}]
}
}
};
Accessing the properties of an object has nothing to do with Handlebars. If you dealing with JSON and you wish to access it in general bracket or dot notation, you must first parse the JSON into a JavaScript object using the JSON.parse() function.
After this is done, you may access the properties as follows.
var property = newData['NEARBY_LIST']['100'].RestaurantName; // "Chennai Tiffin"
Here is a fiddle to illustrate.
http://jsfiddle.net/qzm0cygu/2/
I'm not entirely sure what you mean, but if your question is how you can use/read the data in newData, try this:
newData = JSON.parse(newData); //parses the JSON into a JavaScript object
Then access the object like so:
newData.NEARBY_LIST //the object containing the array
newData.NEARBY_LIST[0] //the first item (key "100")
newData.NEARBY_LIST[1] //the second item (key "101")
newData.NEARBY_LIST[0][0] //the first field of the first item (key "RestaurantID", value "100")
newData.NEARBY_LIST[0][2] //the third field of the first item (key "RestaurantName", value "Chennai Tiffin")
newData.NEARBY_LIST[0][3][0] //the first field of the fourth field of the first item (key "startTime", value "11:00")
I hope this was what you were looking for.
EDIT: as Siddharth points out, the above structure does assume you have arrays. If you are not using arrays you can access the properties by using their names as if they're in an associative array (e.g. newData["NEARBY_LIST"]["100"]. The reason I say "properties" and "as if" is because technically JavaScript doesn't support associative arrays. Because they are technically properties you may also access them like newData.NEARBY_LIST (but I don't recommend that in this case as a property name may not start with a number, so you would have to use a mix of the different notations).
On that note, I would recommend using arrays because it makes so many things easier (length checks, for example), and there are practically no downsides.
EDIT2: also, I strongly recommend using the same camelcasing conventions throughout your code. The way you currently have it (with half your properties/variables starting with capitals (e.g. "RestaurantName", "RestaurantID") and the other half being in lowerCamelCase (e.g. "listTime", "startTime")) is just asking for people (you or colleagues) to make mistakes.

Can't access value from JSON

I have this JSON string:
{
"attachedFiles": [{
"link": "/site.com/dir?id=12993&SESSION=40af90dd-c1f3-4678-93e5-a4b36f3597b0&SESSIONTICKET=SESS:67bf209be2",
"fileName": "file1.txt",
"docDate": "24.02.2014",
"docTime": "13:54",
"docId": "12993"
}],
"requestId": 48,
"tasksId": 0,
"workId": 10558
}
I'm converting it like this:
var resdata = xhr.responseText; // the string response from the server
var resObj = JSON.parse(resdata);
And then I'm trying to access(print the value) fileName inside of the attachedFiles object by the code below:
console.log(resObj.attachedFiles.fileName);
It always returns undefined. I know that I'm mising something real small here, but I'm not able to spot it.
attachedFiles is array. So try access the array content using indexer
resObj.attachedFiles[0].fileName // 0th index, 1st Element
To access all elements in the array. Thanks to #Cerbus comment
for(var i = 0, l = resObj.attachedFiles.length; i < l;i++)
{
console.log(resObj.attachedFiles[i].fileName);
}
attachedFiles is an array so use indexer it is zero based index so first element will be at zero index.
console.log(resObj.attachedFiles[0].fileName);

Adding a new array element to a JSON object

I have a JSON format object I read from a JSON file that I have in a variable called teamJSON, that looks like this:
{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"}]}
I want to add a new item to the array, such as
{"teamId":"4","status":"pending"}
to end up with
{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"},{"teamId":"4","status":"pending"}]}
before writing back to the file. What is a good way to add to the new element? I got close but all the double quotes were escaped. I have looked for a good answer on SO but none quite cover this case. Any help is appreciated.
JSON is just a notation; to make the change you want parse it so you can apply the changes to a native JavaScript Object, then stringify back to JSON
var jsonStr = '{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"}]}';
var obj = JSON.parse(jsonStr);
obj['theTeam'].push({"teamId":"4","status":"pending"});
jsonStr = JSON.stringify(obj);
// "{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"},{"teamId":"4","status":"pending"}]}"
var Str_txt = '{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"}]}';
If you want to add at last position then use this:
var parse_obj = JSON.parse(Str_txt);
parse_obj['theTeam'].push({"teamId":"4","status":"pending"});
Str_txt = JSON.stringify(parse_obj);
Output //"{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"},{"teamId":"4","status":"pending"}]}"
If you want to add at first position then use the following code:
var parse_obj = JSON.parse(Str_txt);
parse_obj['theTeam'].unshift({"teamId":"4","status":"pending"});
Str_txt = JSON.stringify(parse_obj);
Output //"{"theTeam":[{"teamId":"4","status":"pending"},{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"}]}"
Anyone who wants to add at a certain position of an array try this:
parse_obj['theTeam'].splice(2, 0, {"teamId":"4","status":"pending"});
Output //"{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"4","status":"pending"},{"teamId":"3","status":"member"}]}"
Above code block adds an element after the second element.
First we need to parse the JSON object and then we can add an item.
var str = '{"theTeam":[{"teamId":"1","status":"pending"},
{"teamId":"2","status":"member"},{"teamId":"3","status":"member"}]}';
var obj = JSON.parse(str);
obj['theTeam'].push({"teamId":"4","status":"pending"});
str = JSON.stringify(obj);
Finally we JSON.stringify the obj back to JSON
In my case, my JSON object didn't have any existing Array in it, so I had to create array element first and then had to push the element.
elementToPush = [1, 2, 3]
if (!obj.arr) this.$set(obj, "arr", [])
obj.arr.push(elementToPush)
(This answer may not be relevant to this particular question, but may help
someone else)
Use spread operator
array1 = [
{
"column": "Level",
"valueOperator": "=",
"value": "Organization"
}
];
array2 = [
{
"column": "Level",
"valueOperator": "=",
"value": "Division"
}
];
array3 = [
{
"column": "Level",
"operator": "=",
"value": "Country"
}
];
console.log(array1.push(...array2,...array3));
For example here is a element like button for adding item to basket and appropriate attributes for saving in localStorage.
'<i class="fa fa-shopping-cart"></i>Add to cart'
var productArray=[];
$(document).on('click','[cartBtn]',function(e){
e.preventDefault();
$(this).html('<i class="fa fa-check"></i>Added to cart');
console.log('Item added ');
var productJSON={"id":$(this).attr('pr_id'), "nameEn":$(this).attr('pr_name_en'), "price":$(this).attr('pr_price'), "image":$(this).attr('pr_image')};
if(localStorage.getObj('product')!==null){
productArray=localStorage.getObj('product');
productArray.push(productJSON);
localStorage.setObj('product', productArray);
}
else{
productArray.push(productJSON);
localStorage.setObj('product', productArray);
}
});
Storage.prototype.setObj = function(key, value) {
this.setItem(key, JSON.stringify(value));
}
Storage.prototype.getObj = function(key) {
var value = this.getItem(key);
return value && JSON.parse(value);
}
After adding JSON object to Array result is (in LocalStorage):
[{"id":"99","nameEn":"Product Name1","price":"767","image":"1462012597217.jpeg"},{"id":"93","nameEn":"Product Name2","price":"76","image":"1461449637106.jpeg"},{"id":"94","nameEn":"Product Name3","price":"87","image":"1461449679506.jpeg"}]
after this action you can easily send data to server as List in Java
Full code example is here
How do I store a simple cart using localStorage?

Categories