Display JSON data to HTML page using JavaScript - javascript

First time being exposed to JSON so please explain like I'm 5 without the jargon.
I have been given a JSON file like this and need to display these items in a list in HTML.
A lot of examples have the JSON object assigned to a variable- this isn't assigned to a variable so I'm unsure how to reference it.
How can I access and display everything in product list.
In my html I have linked to a script.js file and also this json file.
HTML
<h1>My Cart</h1>
<div id="cart">
<h2>Cart Items</h2>
<ul id="cartItemsList">
</ul>
</div>
JSON
"basket": {
"productList": [{
"product": {
"id": "111",
"name": "Dog",
"shortDescription": "<p>Mans best friend</p>",
},
"category": "Canine",
"availability": "In Stock",
"variationType": {
"name": "Breed",
"value": "Collie"
}
},
"quantity": 1,
"price": "$53.00"
}, {
"product": {
"id": "112",
"name": "Dog",
"shortDescription": "<p>Not so best friend</p>",
"category": "feline",
"availability": "Low In Stock",
"variationType": {
"name": "breed",
"value": "Maine Coon"
}
},
"quantity": 1,
"price": "$49.00"
}, {
"product": {
"id": "113",
"name": "Rabbit",
"shortDescription": "Likes carrots",
"category": "cuniculus",
"availability": "In Stock"
},
"quantity": 1,
"price": "$66.00"
}]
}
JavaScript
var products = document.getElementById("cartItemsList");
cartItemsList.innerHTML = "<li>" + product + "</li>";

If you are loading this from an external file, you will need Ajax or a similar type of call. To use Ajax, you'll have to add a library called jQuery to your project's HTML file. Then you can call your JSON without referencing it as a javascript variable as you see in the following working code snippet.
/* I put your JSON into an external file, loaded from github */
var url = "https://raw.githubusercontent.com/mspanish/playground/master/jessica.json";
/* this tells the page to wait until jQuery has loaded, so you can use the Ajax call */
$(document).ready(function(){
$.ajax({
url: url,
dataType: 'json',
error: function(){
console.log('JSON FAILED for data');
},
success:function(results){
/* the results is your json, you can reference the elements directly by using it here, without creating any additional variables */
var cartItemsList = document.getElementById("cartItemsList");
results.basket.productList.forEach(function(element) {
cartItemsList.insertAdjacentHTML( 'beforeend',"<li>" + element.product.name + " : " + element.price+ " </li>");
}); // end of forEach
} // end of success fn
}) // end of Ajax call
}) // end of $(document).ready() function
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>My Cart</h1>
<div id="cart">
<h2>Cart Items</h2>
<ul id="cartItemsList">
</ul>
</div>

if you want to parse an object:
function logTheObj(obj) {
var ret = "";
for (var o in obj) {
var data = obj[o];
if (typeof data !== 'object') {
ret += "<li>" + o + " : " + data + "</li>";
} else {
ret += "<li>" + o + " : " + logTheObj(data) + "</li>";
}
}
return "<ul>" + ret + "</ul>";
}
If your object is in a string:
logTheObj(JSON.parse(jsonString));

JavaScript version using external json file from previous answer by Stacey Reiman
const products = document.getElementById("cartItemsList");
/* get basket items from JSON */
class Basket {
async cartItems() {
try {
let result = await fetch('https://raw.githubusercontent.com/mspanish/playground/master/jessica.json')
let data = await result.json()
// return data
/* destructuring data */
let basketItems = data.basket.productList
basketItems = basketItems.map(item =>{
const price = item.price
const{id,name,shortDescription,category,availability} = item.product
const breed = item.product.variationType
const quantity = item.quantity
return {price,id,name,shortDescription,category,availability,quantity,breed}
})
return basketItems
} catch (error) {
console.log(error)
}
}
}
/* Display stuff from the basket */
class Display {
displayBasket(basket) {
//console.log(basket)
let result = ""
basket.forEach((item)=>{
result += `
<li>
id : ${item.id}
name: ${item.name}
price: ${item.price}
availability: ${item.availability}
category : ${item.category}
quantity : ${item.quantity}
shortDescription : ${item.shortDescription}
</li>
`})
cartItemsList.innerHTML = result
}
}
document.addEventListener("DOMContentLoaded", ()=>{
const basket = new Basket()
const display = new Display()
basket.cartItems().then(basket => display.displayBasket(basket))
})
<h1>My Cart</h1>
<div id="cart">
<h2>Cart Items</h2>
<ul id="cartItemsList">
</ul>
</div>

First, you have to convert the json from long string to acutely js object.
you doing so by the JSON.parse command. like so:
let jsObj = JSON.parse( youreJsonString);
Them, you can loop throw youre products in your productList and build your html code, like so:
var products = document.getElementById("cartItemsList");
jsObj.basket.productList.forEach( function(product ) {
cartItemsList.innerHTML = "<li>" + product.name + " : " + product.price+ " </li>";
});

Unless you use an Ajax call or something similar to load external JSON, you need to convert the JSON you've provided into an object that you can reference as a variable. Also, your JSON is not valid. I tried correcting it here, and am going to reference your JSON as an object you can reference via a variable named obj. Here is a working code snippet.
var obj = {
"basket": {
"productList": [{
"product": {
"id": "111",
"name": "Dog",
"shortDescription": "<p>Mans best friend</p>",
"category": "Canine",
"availability": "In Stock",
"variationType": {
"name": "Breed",
"value": "Collie"
}
},
"quantity": 1,
"price": "$53.00"
}, {
"product": {
"id": "112",
"name": "Dog",
"shortDescription": "<p>Not so best friend</p>",
"category": "feline",
"availability": "Low In Stock",
"variationType": {
"name": "breed",
"value": "Maine Coon"
}
},
"quantity": 1,
"price": "$49.00"
}, {
"product": {
"id": "113",
"name": "Rabbit",
"shortDescription": "Likes carrots",
"category": "cuniculus",
"availability": "In Stock"
},
"quantity": 1,
"price": "$66.00"
}]
}
}
var cartItemsList = document.getElementById("cartItemsList");
obj.basket.productList.forEach(function(element) {
cartItemsList.insertAdjacentHTML( 'beforeend',"<li>" + element.product.name + " : " + element.price+ " </li>");
});
<h1>My Cart</h1>
<div id="cart">
<h2>Cart Items</h2>
<ul id="cartItemsList">
</ul>
</div>

Related

I need to loop this array

I use ajax to get a array from Economic and i would like to loop though it. The array (sortned):
{
"collection": [
{ "customerNumber": 1, "email": "jo+billing#test.com", "name": "Tester Test" }
, { "customerNumber": 2, "name": "Demo Name" }
]
, "metaData": { "more array" }
, "pagination": { "more array"}
, "self": "some url"
}
The jquery I think I need to use but give me a error: (TypeError: cannot use 'in' operator to search for 'length' in '{
"collectio...')
$.ajax({}).always(function (data) {
var options = $('#example').attr('options');
var substr = JSON.stringify(data, null, 4);
//-----------loop part------------
$.each((substr), function(i, val1) {
$.each(val1.customerNumber, function(a, val3) {
var CustInfo = val1[a]["name"] + " " + val1[a]["email"];
options[options.length] = new Option(CustInfo, val1[a]["customerNumber"]);
});
});
});
I am only interested in the values in "collection" and I want a select box with the customers info in it. like this:
<select>
<option value="1">Tester Test jo+billing#test.com</option>
<option value="2">Demo Name</option>
</select>
First, you don't have to use JSON.stringify() that will convert your response object data to a string that you can't loop through the attributes.
I am only interested in the values in "collection".
Then no need for two loops just use the data.collection :
$.ajax({}).always(function (data) {
var options = $('#example').attr('options');
$.each((data.collection), function(i, obj) {
var CustInfo = obj["name"] + " " + obj["email"];
options[options.length] = new Option(CustInfo, obj["customerNumber"]);
});
});
data = {
"collection": [{
"customerNumber": 1,
"email": "jo+billing#test.com",
"name": "Tester Test"
}, {
"customerNumber": 2,
"name": "Demo Name"
}],
"metaData": [],
"pagination": [],
"self": "some url"
};
$.each((data.collection), function(i, val1) {
var CustInfo = val1["name"] + " " + val1["email"];
console.log(CustInfo, val1["customerNumber"]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Represent data from json file in rating stars without jquery!! pure javaScript

I am trying to load the data from my JSON file using javaScript and i need to represent the hotel2show.rating in form of stars, just represent them dependig on the value from 'hotels.json'
Here is my JavaScript
function getHotels(i){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function()
{
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
hotel=JSON.parse(xhr.responseText);
var hotel2show = hotel.hotels[i];
document.getElementById("img-container").innerHTML =
"<img src='"+hotel2show.imgUrl+"'>"+
"<p id='name'><strong>"+ hotel2show.name +"</strong></p>" +"<br/>" + "<p id='rating'><strong>"+ hotel2show.rating +"</strong></p>" +"<br/>" + "<br/>" +"<p id='price'><strong>"+ '£' +hotel2show.price +
"</strong></p>" + "<p id='text'><strong>"+ 'Total hotel stay' +"</strong></p>";
} else {
alert("Ha existido un error con el servidor");
}
}
};
xhr.open("GET",'hotels.json', true);
xhr.send();
and here is my html
<div class="container">
<div id="lista">
<ul>
<button onclick="getHotels(0)">Hotel Sunny Palms</button>
<button onclick="getHotels(1)">Hotel Snowy Mountains</button>
<button onclick="getHotels(2)">Hotel Windy Sails</button>
<button onclick="getHotels(3)">Hotel Middle Of Nowhere</button>
</ul>
</div>
<div class="banner-section" id="img-container">
</div>
and my hotels.json
"hotels": [
{
"name": "Hotel Sunny Palms",
"imgUrl": "imgs/sunny.jpg",
"rating": 5,
"price": 108.00
},
{
"name": "Hotel Snowy Mountains",
"imgUrl": "imgs/snowy.jpg",
"rating": 4,
"price": 120.00
},
{
"name": "Hotel Windy Sails",
"imgUrl": "imgs/windy.jpg",
"rating": 3,
"price": 110.00
},
{
"name": "Hotel Middle of Nowhere",
"imgUrl": "imgs/nowhere.jpg",
"rating": 4,
"price": 199.00
}
]
any help is appreciated
For example..if you have UTF-8 charset then this should perhaps be fine. The key is createElement function by which you can construct your DOM as you wish.
var hotels = [{
"name": "Hotel Sunny Palms",
"imgUrl": "imgs/sunny.jpg",
"rating": 5,
"price": 108.00
}, {
"name": "Hotel Snowy Mountains",
"imgUrl": "imgs/snowy.jpg",
"rating": 4,
"price": 120.00
}, {
"name": "Hotel Windy Sails",
"imgUrl": "imgs/windy.jpg",
"rating": 3,
"price": 110.00
}, {
"name": "Hotel Middle of Nowhere",
"imgUrl": "imgs/nowhere.jpg",
"rating": 4,
"price": 199.00
}];
buildRating(hotels);
function buildRating(data) {
data.forEach(function(v) {
createRatingElement(v.rating);
});
}
function createRatingElement(numberOfStars) {
var wrapper = document.createElement('div');
for (var i = 1; i <= 5; i++) {
var span = document.createElement('span')
span.innerHTML = (i <= numberOfStars ? '★' : '☆');
span.className = (i <= numberOfStars ? 'high' : '');
wrapper.appendChild(span);
}
document.getElementById('img-container').appendChild(wrapper);
}
span {
display: inline-block;
position: relative;
width: 1.2em;
height: 1.2em;
color: black;
}
.high {
color: rgb(217, 211, 0);
}
<div class="banner-section" id="img-container">
</div>
Also, jsfiddle: https://jsfiddle.net/md4708oq/
I assume you know how to parse out your ratings, right? If you are just displaying single star values (whole numbers), then you can just write out a class onto a span element where you would style it with CSS to change what the background image would be.
So, you could make it show 1-5 stars with 4 different images.
It's a solution; not the cleanest or most scalable, but it works for this situation.
So first off this is a nightmare.
Let's clean it up a bit?
var appendString = [];
appendString[0] = "<img src='"+hotel2show.imgUrl+"'>";
appendString[1] = "<p id='name'><strong>"+ hotel2show.name +"</strong></p><br/>";
switch(hotel2show.rating):
case(1):
appendString[2] = "<p id='rating' class='rating-1'><strong>";
break;
case(2):
appendStirng[2] = "<p id='rating' class='rating-2><strong>";
break;
//etc
appendString[3] = hotel2show.rating +"</strong></p>";
appendString[4] = "<br/><br/>";
appendString[5] = "<p id='price'><strong>'£'" + hotel2show.price + "</strong></p>";
appendString[6] = "<p id='text'><strong>"+ 'Total hotel stay' +"</strong></p>";
document.getElementById("img-container").innerHTML = appendString.join(' ');
Note: the switch statement syntax may be incorrect.
You will have to use AJAX calls to retrieve JSON data and then use pure javascript to parse the JSON data and use it to display your html accordingly. Let me know if this is what you are looking for i will help you out with the same.

How to parse nested JSON in Javascript?

I am trying to parse and show JSON data (product catalog) using XMLHttpRequest method. I am able to display the brands and their names, but not able to showcase list of products progmatically.
Here is the sample JSON request:
{
"products": {
"laptop": [{
"brand": "sony",
"price": "$1000"
}, {
"brand": "acer",
"price": "$400"
}],
"cellphone": [{
"brand": "iphone",
"price": "$800"
}, {
"brand": "htc",
"price": "$500"
}],
"tablets": [{
"brand": "iPad",
"price": "$800"
}, {
"brand": "htc-tab",
"price": "$500"
}]
}
}
Right now I am using following code to show data in tabluar form:
function loadJSON() {
var data_file = "http://localhost/AJAX/productcatalog.json";
var http_request = new XMLHttpRequest();
http_request.onreadystatechange = function () {
if ((http_request.readyState == 4) && (http_request.status == 200)) {
// Javascript function JSON.parse to parse JSON data
var jsonObj = JSON.parse(http_request.responseText);
data = '<table border="2"><tr><td>Type</td><td>Brand</td><td>Price</td></tr>';
var i = 0;
debugger;
for (i = 0; i < jsonObj["products"].laptop.length; i++)
{
obj = jsonObj["products"].laptop[i];
data = data + '<tr><td>laptop</td><td>' + obj.brand + '</td><td>' + obj.price + '</td></tr>';
}
for (i = 0; i < jsonObj["products"].cellphone.length; i++)
{
obj = jsonObj["products"].cellphone[i];
data = data + '<tr><td>laptop</td><td>' + obj.brand + '</td><td>' + obj.price + '</td></tr>';
}
for (i = 0; i < jsonObj["products"].tablets.length; i++)
{
obj = jsonObj["products"].tablets[i];
data = data + '<tr><td>laptop</td><td>' + obj.brand + '</td><td>' + obj.price + '</td></tr>';
}
data += '</table>';
document.getElementById("demo").innerHTML = data;
}
}
http_request.open("GET", data_file, true);
http_request.send();
}
Question What is the way to fetch product list , i.e. products, cellphone and tablets ? Right now I have hardcoded that in order to fetch complete list of brands. Please advice. (I want to use plain javascript and not jquery)
Thanks!
It sounds like what you're missing is the "How do I iterate over an object when I don't know all the keys".
An object is a set of key, value pairs. You can use for/in syntax: for( var <key> in <object> ){} to get each key.
For your use case it might be something like:
var products = jsonObject['products'];
for( var productName in products ){
//productName would be "laptop", "cellphone", etc.
//products[productName] would be an array of brand/price objects
var product = products[productName];
for( var i=0; i<product.length; i++ ){
//product[i].brand
//product[i].price
}
}
In practice, I might use something a little less verbose, but this makes it easier to understand what is going on.
To achieve the expected i have used for loop and HTML DOM createElement() Method
var product_catalog = {
"products": {
"laptop": [{
"brand": "sony",
"price": "$1000"
}, {
"brand": "acer",
"price": "$400"
}],
"cellphone": [{
"brand": "iphone",
"price": "$800"
}, {
"brand": "htc",
"price": "$500"
}],
"tablets": [{
"brand": "iPad",
"price": "$800"
}, {
"brand": "htc-tab",
"price": "$500"
}]
}
};
var output = document.querySelector('#product tbody');
function build(JSONObject) {
/**get all keys***/
var keys = Object.keys(JSONObject);
/**get all subkeys***/
var subkeys = Object.keys(JSONObject[keys]);
console.log(subkeys);
/**loop sub keys to build HTML***/
for (var i = 0, tr, td; i < subkeys.length; i++) {
tr = document.createElement('tr');
td = document.createElement('td');
td.appendChild(document.createTextNode(subkeys[i]));
tr.appendChild(td);
output.appendChild(tr);
}
};
build(product_catalog);
HTML:
Coepen URL for reference- http://codepen.io/nagasai/pen/xOOqMv
Hope this works for you :)
Look at this example:
var x = data.key1.children.key4;
var path = "data";
function search(path, obj, target) {
for (var k in obj) {
if (obj.hasOwnProperty(k))
if (obj[k] === target)
return path + "['" + k + "']"
else if (typeof obj[k] === "object") {
var result = search(path + "['" + k + "']", obj[k], target);
if (result)
return result;
}
}
return false;
}
//Then for evry node that you need you can call the search() function.
var path = search(path, data, x);
console.log(path); //data['key1']['children']['key4']
I think this is what you're asking about, you can use Object.keys to get the properties of an object, then loop through them afterward.
var data = {
"products": {
"laptop": [{
"brand": "sony",
"price": "$1000"
}, {
"brand": "acer",
"price": "$400"
}],
"cellphone": [{
"brand": "iphone",
"price": "$800"
}, {
"brand": "htc",
"price": "$500"
}],
"tablets": [{
"brand": "iPad",
"price": "$800"
}, {
"brand": "htc-tab",
"price": "$500"
}]
}
}
var typesOfProducts = Object.keys(data.products)
console.log(typesOfProducts)
document.getElementById('output').textContent = typesOfProducts.toString()
//Then, to loop through
var i = -1,
len = typesOfProducts.length
function handleProduct(productType) {
console.log("This is the " + productType + " data.")
console.log(data.products[productType])
}
while (++i < len) {
handleProduct(typesOfProducts[i])
}
<div id="output"></div>
It sounds like what you're looking for is just an array of the keys of the "products" object. Example:
Products: ["laptop", "cellphone", "tablets"];
If so, I would just run your json object through javascript's Object.keys() method.
var jsonObj = JSON.parse(http_request.responseText);
var products = Object.keys(jsonObj.products);
// products = ["laptop", "cellphone", "tablets"];

searching through Json in JavaScript

I have a Json which have hierarchy of folders and files in it
I am trying to get number of file in a folder and its sub-folders by a folder Id
Here is the json
var jsonStr = {
"hierarchy": {
"date": "2014/09/24 15:21:23",
"folder": {
"name": "Root",
"id": "Root",
"file": [{
"id": "22U2621210__PIN_検査報告書Ver1.0_20140923162232.xls"
}, {
"id": "C22-1(EU仕様)_20140923162409.xlsx"
}, {
"id": "Machine_Inspection_20140923162329.xlsx"
}],
"folder": {
"name": "Level-1",
"id": "1411396172645",
"file": {
"id": "22U2621210__PIN_検査報告書Ver1.0_20140923162232.xls"
},
"folder": {
"name": "123",
"id": "1411538469568",
"file": [{
"id": "C22-1(EU仕様)_20140923162409.xlsx"
}, {
"id": "Machine_Inspection_20140923162329.xlsx"
}]
}
}
}
}
};
all the folders are with names and ids, if want to get number of files in that specific folder and its subfolders by searching with its id
for example if I put folder name "123" and id "1411538469568" it should give me only 2 files which are "C22-1(EU仕様)_20140923162409.xlsx" and "Machine_Inspection_20140923162329.xlsx" but if i put folder name "Root" and Id= "Root" it should return me id's of all files
Here is the Fiddle on which i am working on http://jsfiddle.net/ma3kno2o/
You can use Defiant.js
Here is a Fiddle for your concrete search scenario to pull the file IDs of the element with ID: root and Name: root:. I am using Defiant.js in this example:
http://jsfiddle.net/3z8mqr3u/1/
Defiant.js is superior to the custom search in the answer by #Cheery, to get the IDs of the files i had to use one line of code:
var ids = JSON.search(json, "//*[name = 'Root' and id = 'Root']/file/id");
it is much less error-prone for searching dynamic data. Defiant.js uses XPath expressions. Check this link to learn more:
http://defiantjs.com/
Here are some other options:
You can use plain JQuery
How to search JSON tree with jQuery
You can use JsonPath. It's like XPath for JSON files. You can do stuff like:
$..folder.file
http://goessner.net/articles/JsonPath/
https://code.google.com/p/jsonpath/
https://github.com/s3u/JSONPath
You can use Json-Query. It has it-s own language for deep queries. e.g.:
var data = {
grouped_people: {
'friends': [
{name: 'Steve', country: 'NZ'},
{name: 'Bob', country: 'US'}
],
'enemies': [
{name: 'Evil Steve', country: 'AU'}
]
}
}
jsonQuery('grouped_people[][country=NZ]', {data: data})
https://github.com/mmckegg/json-query
If you dont like any of these here you can find more options:
Is there a query language for JSON?
Not a nicest (sorry, 4am) solution, but the straight way through recursion..
Your structure does not support, in a normal way, same-level folders, so I reconfigured it, togerther with the code for it:
http://jsfiddle.net/ma3kno2o/5/
function getFiles(id)
{
var files = searchFolders(jsonStr.hierarchy.folders, false);
alert('Found ' + files.length + " files\n" + JSON.stringify(files));
function searchFolders(tree, count_files)
{
var data = [];
$.each(tree, function(key, val) {
var into = !count_files ? val.id == id : count_files;
if (val.files && into)
$.merge(data, getFiles(val.files));
if (val.folders)
$.merge(data, searchFolders(val.folders, into));
});
return data;
}
function getFiles(tree)
{
var files = [];
if (tree.id) return [tree.id];
$.each(tree, function(key,val) {
if (val.id)
files.push(val.id);
});
return files;
};
}
var jsonStr = {
"hierarchy": {
"date": "2014/09/24 15:21:23",
"folders": [{
"name": "Root",
"id": "Root",
"files": [{
"id": "file.1"
}, {
"id": "file.2"
}, {
"id": "file.3"
}],
"folders": [{
"name": "Level-1",
"id": "1411396172645",
"files": {
"id": "file.4"
},
"folders": [{
"name": "123",
"id": "1411538469568",
"files": [{
"id": "file.5"
}, {
"id": "file.6"
}]},
{
"name": "123",
"id": "1411538469569",
"files": [{
"id": "file.7"
}, {
"id": "file.8"
}]
}]
}]
}]
}
};
The old code will not work, so I rewrote it for your new varia
http://jsfiddle.net/ma3kno2o/8/
function getFiles(id)
{
var stp = -1;
var files = searchFolders(jsonStr.hierarchy, false);
alert('Found ' + files.length + " files\n" + JSON.stringify(files));
function searchFolders(tree, count_files)
{
var data = [];
var folders = tree.folder.length > 1 ? tree.folder : [tree.folder];
$.each(folders, function(key, val) {
var into = !count_files ? val.id == id : count_files;
if (val.file && into)
$.merge(data, getFiles(val.file));
if (val.folder)
$.merge(data, searchFolders(val, into));
});
return data;
}
function getFiles(tree)
{
var files = [];
if (tree.id) return [tree.id];
$.each(tree, function(key,val) {
if (val.id)
files.push(val.id);
});
return files;
};
}
var jsonStr= {"hierarchy":{"date":"2014/09/24 18:13:00","folder":{"name":"Root","id":"Root","file":[{"id":"file.1"},{"id":"file.2"},{"id":"file.3"}],"folder":[{"name":"Level-1","id":"1411396172645","file":{"id":"file.4"},"folder":{"name":"123","id":"1411538469568","file":[{"id":"file.5"},{"id":"file.6"}],"folder":{"name":"123-a","id":"1411549962260","file":{"id":"file.7"}}}},{"name":"level-2","id":"1411549976987","file":{"id":"file.8"}}]}}};

Show value of an array from json object once when is duplicate

I'm trying to form a list from json data, see the example What I want is that it will show me the value just once when duplicate values occurs (2x Martini glass, I want it to return just one in the list), but leaves the array as is, i.e. still want to be able to hold all values in the array.
There'd sure be a simple way to achieve this, but i'm not finding it...
var data = {
"cocktails": [{
"name": "Bloody Mary",
"glass": "longdrink",
"ingredients": {
"main": "vodka",
"secondary": "tomato juice",
"addition": "tabasco"
}
}, {
"name": "Daiquiri",
"glass": "martini glass",
"ingredients": {
"main": "white rum",
"secondary": "lime juice",
"addition": "sugar syrup"
}
}, {
"name": "Martini",
"glass": "martini glass",
"ingredients": {
"main": "gin",
"secondary": "vermout",
"addition": "olive"
}
}]
}
$(data.cocktails).each(function () {
var output = "<ul><li>" + this.glass + "</li></ul>";
$('#placeholder').append(output);
});
Create an empty array:
var glasses = [];
Push all the glasses to it.
data.cocktails.forEach(function (el) {
glasses.push(el.glass);
});
Create a deduped array of glasses. This leaves the glasses array intact so you can use it again.
var dedupedGlasses = glasses.filter(function(elem, pos) {
return glasses.indexOf(elem) == pos;
});
Use join to create the HTML list.
var html = '<ul><li>' + dedupedGlasses.join('</li><li>') + '</li></ul>';
And add to the page.
$('#placeholder').append(html);
Demo
The you can use something like this to grab the count for each glasses type:
function getCount(arr) {
return arr.reduce(function(m, e){
m[e] = (+m[e]||0)+1; return m
}, {});
}
console.log(getCount(glasses)); // { longdrink=1, martini glass=2 }
Basically the same as #Andy, though slightly different.
var data = {
"cocktails": [{
"name": "Bloody Mary",
"glass": "longdrink",
"ingredients": {
"main": "vodka",
"secondary": "tomato juice",
"addition": "tabasco"
}
}, {
"name": "Daiquiri",
"glass": "martini glass",
"ingredients": {
"main": "white rum",
"secondary": "lime juice",
"addition": "sugar syrup"
}
}, {
"name": "Martini",
"glass": "martini glass",
"ingredients": {
"main": "gin",
"secondary": "vermout",
"addition": "olive"
}
}]
}
$('#placeholder').append('<ul><li>' + data.cocktails.map(function (cocktail) {
return cocktail.glass;
}).filter(function (glass, index, array) {
return array.indexOf(glass) === index;
}).join('</li><li>') + '</li></ul>');
On jsFiddle
I can just point to a solution where you need to define a new array
var cleanArr = []
$(data.cocktails).each(function () {
if($.inArray(this.glass, cleanArr) === -1) cleanArr.push(this.glass);
var output = "<ul><li>" + this.glass + "</li></ul>";
$('#placeholder').append(output);
});
console.log(cleanArr)
I like the way the array is created, that's why I'm posting this solution but it is not my idea --> taken from:
Remove Duplicates from JavaScript Array
Here is a working jsFiddle for you.
http://jsfiddle.net/Q74pj/1/
And here is what I did:
I used a new function calling uniqueArray to create a new associative array (which would be the quickest to iterate and fill).
You need to create a unique array, or sort it by drink and skip the duplicates.
function uniqueValues (arr) {
//if (arr.length < 2) return arr;
var retVal = {};
for (var i = 0; i < arr.length; i++) {
retVal[arr[i].glass] = arr[i];
}
return retVal;
}
then just use another way to iterate the associate array:
var uniqueArrayValues = uniqueValues(data.cocktails);
for (key in uniqueArrayValues) {
var output = "<ul><li>" + uniqueArrayValues[key].glass + "</li></ul>";
$('#placeholder').append(output);
}

Categories