main.php jQuery code:
$.getJSON('posts.php',function(data){
data.posts.forEach(function(post){
// set variables and append divs to document
})
data.comments.forEach(function(post){
// set variables and append divs to document
})
})
(Old - Works with current jQuery code)
Example object containing 2 posts and 3 comments. Post with id: 5 has 1 comment and post id: 2 has 2 comments.
// the two posts ID: 5 and 2
{"posts":[{
"id":"5",
"image":"link.jpg",
"submitter":"4322309",
"views":"3"
},
{
"id":"2",
"image":"link.jpg",
"submitter":"4322309",
"views":"10"
}],
// now each comment tied to the posts
"comments":[
{
"id":"1",
"submitter":"submitter",
"time":"2435657",
"comment":"comment",
"score":"10",
"postid":"2"
},
{
"id":"2",
"submitter":"submitter",
"time":"2435657",
"comment":"comment",
"score":"10",
"postid":"2"
},
{
"id":"3",
"submitter":"submitter",
"time":"2435657",
"comment":"comment",
"score":"10",
"postid":"5"
}]}
(NEW - Does not work with current jQuery code)
Example object containing 2 posts and 3 comments. Post with id: 5 has 1 comment and post id: 2 has 2 comments.
// the two posts ID: 5 and 2
{
"posts":{
"5": {
"id":"5",
"image":"link.jpg",
"submitter":"4322309",
"views":"3"
},
"2": {
"id":"2",
"image":"link.jpg",
"submitter":"4322309",
"views":"5"
}
},
// now each comment tied to the posts
"comments":{
"2": [{
"id":"1",
"submitter":"submitter",
"time":"2435657",
"comment":"comment",
"score":"10",
"postid":"2"
},
{
"id":"2",
"submitter":"submitter",
"time":"2435657",
"comment":"comment",
"score":"10",
"postid":"2"
}
],
"5": [{
"id":"3",
"submitter":"submitter",
"time":"2435657",
"comment":"comment",
"score":"10",
"postid":"5"
}]
}
}
I'm not sure how to use this JSON object in this new scenario.
Basically how do I loop through this new one?
You can easily iterate like this:-
$.each(data['posts'], function(outerKey, idVal) { //outerKyeas are 2, 5
$.each(idVal, function(innerKey, val) { // innerKeys are id,submitter etc
console.log(innerKey, val);
});
});
Comments can be looped through like the same way.
First option (vanilla JS):
var postObj;
for (var id in data.posts) {
postObj = data.posts[id];
// do your thing
}
var commentList;
for (var id in data.comments) {
commentList = data.comments[id];
commentList.forEach(function(comment) {
// do your thing
});
}
For more info on for...in loops https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
Second Option (jQuery):
$.each(data.posts, function(id, post) {
// do your thing
});
$.each(data.comments, function(id, commentList) {
$.each(commentList, function(index, comment) {
// do your thing. you could also use the forEach loop if you want
});
});
For more info on $.each http://api.jquery.com/jquery.each/
Well I say you need 3 loops here to fetch each comment object like
DEMO
$(data.comments).each(function(index,commentArray){
$.each(commentArray,function(index,value){
$.each(value,function(index1,value1){
console.log(value1);
});
});
});
for Post you can get it with a single loop
$.each(data.posts,function(index,post){
console.log(post);
});
Try $.each coupled with a basic 'for (var post in data.posts)' loop:
var data = {
"posts": {
"5": {
"id": "5",
"image": "link.jpg",
"submitter": "4322309",
"views": "3"
},
"2": {
"id": "2",
"image": "link.jpg",
"submitter": "4322309",
"views": "5"
}
},
// now each comment tied to the posts
"comments": {
"2": [{
"id": "1",
"submitter": "submitter",
"time": "2435657",
"comment": "comment",
"score": "10",
"postid": "2"
}, {
"id": "2",
"submitter": "submitter",
"time": "2435657",
"comment": "comment",
"score": "10",
"postid": "2"
}],
"5": [{
"id": "3",
"submitter": "submitter",
"time": "2435657",
"comment": "comment",
"score": "10",
"postid": "5"
}]
}
};
for (var post in data.posts) {
$.each(data.comments[data.posts[post].id], function() {
alert("Post: " + data.posts[post].id + ", Comment ID: " + this.id + ', Comment Text: "' + this.comment + '"')
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Related
I am trying to iterate through below Collections JSON object. I am trying to find collection elements which have one of the tags from tagArray. Basically this is a filter exercise to have collection elements that have tags as selected from the tagArray.
{
1: {
"description": "AAA",
"tags": [
{
"name": "tag1",
},
{
"name": "tag2",
},
{
"name": "tag3",
},
],
"name": "XYZ",
},
2: {
"description": "BBB",
"tags": [
{
"name": "tag1",
}
],
"name": "CCC",
},
3: {
"description": "xms",
"tags": [],
"name": "Huo",
},
4: {
"description": "asd",
"tags": [],
"name": "TXS",
}
}
tagArray looks like this : [ tag1, tag2, ... ]
I have coded it as below using lodash and it works fine. But I am not sure if I can improve this further and how?
const filterByTags = (collections, filterTags) => {
let filteredCollections = _.pickBy(collections, (collection) => {
let collectionWithTag = false;
_.map(collection.tags, (collectionTag) => {
if (filterTags.indexOf(collectionTag.name) !== -1) {
collectionWithTag = true;
return collectionWithTag;
}
});
return collectionWithTag;
});
return filteredCollections;
};
You don't want to use pickBy but rather filter (Lodash/native)
You don't want to use map but rather some (Lodash/native)
You don't want to use indexOf but rather includes (Lodash/native)
function filterByTags(collections, filterTags) {
return _.filter(collections, collection => {
return _.some(collection.tags, collectionTag => {
return _.includes(filterTags, collectionTag.name);
});
});
}
For example I have a simple JSON, like this:
{
"id": "123",
"author": {
"id": "1",
"name": "Paul"
},
"title": "My awesome blog post",
"comments": [
{
"id": "324",
"commenter": {
"id": "2",
"name": "Nicole"
}
},
{
"id": "325",
"commenter": {
"id": "3",
"name": "Alex"
}
}
]
}
And after normalizing with normalizr and schemas from example
import { normalize, schema } from 'normalizr';
// Define a users schema
const user = new schema.Entity('users');
// Define your comments schema
const comment = new schema.Entity('comments', {
commenter: user
});
// Define your article
const article = new schema.Entity('articles', {
author: user,
comments: [ comment ]
});
const normalizedData = normalize(originalData, article);
I will get this normalized JSON:
{
result: "123",
entities: {
"articles": {
"123": {
id: "123",
author: "1",
title: "My awesome blog post",
comments: [ "324", "325" ]
}
},
"users": {
"1": { "id": "1", "name": "Paul" },
"2": { "id": "2", "name": "Nicole" },
"3": { "id": "3", "name": "Alex" }
},
"comments": {
"324": { id: "324", "commenter": "2" },
"325": { id: "325", "commenter": "3" }
}
}
}
In normalizedData.result, I will get only articles IDs. But what if I need IDs of comments or users. Basically I can get it with Object.keys(), may be is there any other way, normalizr can provide us from API to get this data at step of normalization? I can't find anything about it it API. Or can you suggest any methods to do it, not automatically? Because Object.keys() not looks good for me.
Since the value you're normalizing is an article, the result value from Normalizr will be the Article's ID. As you suggested yourself, if you need to the IDs of a different, nested entity type, you'll have to use something like Object.keys(normalizedData.entities.comments)
Here is the my first JSON Array format...
[
{
"id": "1234",
"caption": "caption1"
},
{
"id": "2345",
"caption": "caption2"
},
{
"id": "3456",
"caption": "caption3"
}
]
and here is another JSON Array Format
[
[
{
"id": "1234",
"value": "value11"
},
{
"id": "2345",
"value": "value12"
},
{
"id": "3456",
"value": "value13"
}
],
[
{
"id": "1234",
"value": "value21"
},
{
"id": "2345",
"value": "value22"
},
{
"id": "3456",
"value": "value23"
}
]
]
The above mentioned Two JSON Arrays, i need to compare each one with Id and need to format a new JSON Array with caption and value using javascript.
[
[
{
"caption" : "caption1",
"value":"value11"
},
{
"caption" : "caption2",
"value":"value12"
},
{
"caption" : "caption3",
"value":"value13"
}
],
[
{
"caption" : "caption1",
"value":"value21"
},
{
"caption" : "caption2",
"value":"value22"
},
{
"caption" : "caption3",
"value":"value23"
}
]
]
Please help me out.
You can do it in many ways. Below I show two variants:
Option 1: Pure JavaScript
In this example the program preindex first array for faster access to it data, and then loops over second array with map() function to create new array of arrays:
// Create index version of first array
var aix = {};
for(var i=0;i<arr1.length;i++) {
aix[arr1[i].id] = arr1[i].caption;
}
// Loop over array of arrays
var res1 = arr2.map(function(arr22){
return arr22.map(function(a){
return {caption:aix[a.id], value:a.value};
}
});
Option 2: Using special SQL library (Alasql)
Here, you can JOIN to arrays automatically with special SQL statement:
var res2 = arr2.map(function(a){
return alasql('SELECT arr1.caption, a.[value] \
FROM ? a JOIN ? arr1 USING id',[a,arr1]);
});
You can try these variants in working snippet below or play with it in jsFiddle.
(Disclaimer: I am the author of Alasql)
var arr1 = [
{
"id": "1234",
"caption": "caption1"
},
{
"id": "2345",
"caption": "caption2"
},
{
"id": "3456",
"caption": "caption3"
}
];
var arr2 = [
[
{
"id": "1234",
"value": "value11"
},
{
"id": "2345",
"value": "value12"
},
{
"id": "3456",
"value": "value13"
}
],
[
{
"id": "1234",
"value": "value21"
},
{
"id": "2345",
"value": "value22"
},
{
"id": "3456",
"value": "value23"
}
]
];
// JavaScript version
var aix = {};
for(var i=0;i<arr1.length;i++) {
aix[arr1[i].id] = arr1[i].caption;
}
var res1 = arr2.map(function(arr22){
return arr22.map(function(a){
return {caption:aix[a.id], value:a.value};
});
});
document.getElementById("res1").textContent = JSON.stringify(res1);
// Alasql version
var res2 = arr2.map(function(a){
return alasql('SELECT arr1.caption, a.[value] FROM ? a JOIN ? arr1 USING id',[a,arr1]);
});
document.getElementById("res2").textContent = JSON.stringify(res2);
<script src="http://alasql.org/console/alasql.min.js"></script>
<p>Varian 1: JavaScript</p>
<div id="res1"></div>
<p>Variant 2: Alasql</p>
<div id="res2"></div>
This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 9 years ago.
I need to fetch the values from this JSON in my java script:
[{
"selectionName": "Select",
"subSelections": [{
"id": 4,
"subSelectionName": "Select",
"description": "Deepmala"
}
]
}, {
"selectionName": "week14",
"subSelections": [{
"id": 7,
"subSelectionName": "1",
"description": ""
}
]
}, {
"selectionName": "test",
"subSelections": [{
"id": 6,
"subSelectionName": "test",
"description": ""
}
]
}, {
"selectionName": "select",
"subSelections": [{
"id": 3,
"subSelectionName": "sub-select",
"description": "Created by Prakash"
}
]
}, {
"selectionName": "testcreate",
"subSelections": [{
"id": 1,
"subSelectionName": "testcreate",
"description": ""
}
]
}, {
"selectionName": "by htmlwidget",
"subSelections": [{
"id": 5,
"subSelectionName": "by htmlwidget",
"description": "created by html widget"
}
]
}
]
Any suggestions?
You could use something like JSONSelect to extract certain values.
http://jsonselect.org/
Here's an example of how to use it:
(found in this JSFiddle)
$(function(){
/*
Json as easy as SQL ??? RT #lloydhilaiel JSONSelect - CSS-like selectors for JSON - http://jsonselect.org
Testing...
*/
var jsonData = {
"name": {
"first": "Lloyd",
"last": "Hilaiel"
},
"favoriteColor": "yellow",
"languagesSpoken": [
{
"language": "Bulgarian",
"level": 2},
{
"language": "English",
"level": 1},
{
"language": "Spanish",
"level": 7}
]
};
var selector = '.name > *'; // xPath CSS like selector
try {
var resultObj = JSONSelect.match(selector, jsonData);
console.log(typeof resultObj);
console.log(resultObj);
console.log('- - - - -');
JSONSelect.forEach(selector, jsonData, function(resultObj) {
console.log(typeof resultObj);
console.log(resultObj);
console.log('- - - - -');
$('body').append('<p>' + $.trim(JSON.stringify(resultObj, null, ' ')) + '</p>');
});
} catch(e) { console.log(e); }
});
JSON objects are easy to handle
var JSON = //Your JSON Object
JSON[0].selectName //returns 'Select'
JSON[0].subSelections[0].id //returns 4
and so on.
Any array objects can be treated as arrays. Any mapped objects can be returned by using the key like a field name for the JSON object.
I have a JSON and I need to get this JSON and put in the html as a ul li list. It gets the value as object and displays [object Object] in html. If I modify the json then it works. so there is probably something wrong in my script where I am not able to loop throught he json file properly. Can some one help please:
MY JSON IS:
[
{
"us":"USA"
},
{
"fr":"FRANCE"
},
{
"es":"Spain"
},
{
"sa":"South Africa"
}
]
AND JS IS
<script>
$.getJSON('jsonfile', function(data) {
var items = [];
$.each(data ,function(key,val) {
items.push('<li id="'+ key +'">' + val +'</li>');
});
$('<ul />' , {
'class':'new-div',
html:items.join('')
}).appendTo('body');
});
</script>
UPDATED JSON:
[
{
"items":
{
"item":
[
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}
]
}
}
]
The data you're looping over is the array, which has objects. So your key will be 0, 1, etc., and the val will be the object at that position in the array.
Your JSON structure actually makes it a bit of a pain to output, because each of your objects only has one property, but the property name varies from object to object. You can do it, by looping over the object properties even though there's only one of them:
var items = [];
$.each(data ,function(outerKey, outerVal) { // <== Loops through the array
$.each(outerVal, function(key, val) { // <== "Loops" through each object's properties
items.push('<li id="'+ key +'">' + val +'</li>');
});
});
...but I'd change the JSON structure instead. For instance, assuming the keys are unique, your original code would work with this structure:
{
"us":"USA",
"fr":"FRANCE",
"es":"Spain",
"sa":"South Africa"
}