I am having trouble to display the top tracks of a searched artist using the LastFM api to get data. The api returns an object toptracks. I would like to grab details about each of the top tracks from that api data.
I am not sure if I am on the right track. Can someone take a look and let me know if I am doing something wrong?
Sample data from api:
{
"toptracks": {
"track": [{
"name": "Best I Ever Had",
"playcount": "3723918",
"listeners": "1086968",
"mbid": "00bde944-7562-446f-ad0f-3d4bdc86b69f",
"url": "https://www.last.fm/music/Drake/_/Best+I+Ever+Had",
"streamable": "0",
"artist": {
"name": "Drake",
"mbid": "b49b81cc-d5b7-4bdd-aadb-385df8de69a6",
},
"#attr": {
"rank": "1"
}
},
{
"name": "Forever",
"playcount": "1713492",
"listeners": "668998",
"url": "https://www.last.fm/music/Drake/_/Forever",
"streamable": "0",
"artist": {
"name": "Drake",
"mbid": "b49b81cc-d5b7-4bdd-aadb-385df8de69a6",
},
"#attr": {
"rank": "2"
}
}
}
function renderTracks(trackArray) {
function createHTML(track){
return `<h1>${track.name}</h1>
<h2>${track.artist[0]}</h2>
<h3>${toptracks[1].rank}</h3>
<h3>${track.playcount}</h3>`;
};
trackHTML = trackArray.map(createHTML);
return trackHTML.join("");
};
var searchString = $(".search-bar").val().toLowerCase();
var urlEncodedSearchString = encodeURIComponent(searchString);
const url = "lastFMwebsite"
axios.get(url + urlEncodedSearchString).then(function(response) {
// createHTML.push(response.data.track);
// $(".tracks-container").innerHTML = renderTracks(response.data.track);
// comented out old code above
createHTML.push(response.toptracks.track);
$(".tracks-container").innerHTML = renderTracks(response.toptracks.track);
})
I've notice that you have not parsed the response:
axios.get(url + urlEncodedSearchString).then(function(response) {
var parsed = JSON.parse(response);
$(".tracks-container").innerHTML = renderTracks(parsed.toptracks.track)
});
Another correction that I can suggest is to change the track.artist[0] to track.artist["name"] once this property returns an object instead of an array.
And about this: <h3>${toptracks[1].rank}</h3>. You will be not able to access that property because at your function you are providing just the trackproperty.
In this case you have two options: provide the whole response array or add a new parameter providing this.
function renderTracks(trackArray) {/**...*/};
//...
$(".tracks-container").innerHTML = renderTracks(parsed.toptracks)
Or
function renderTracks(trackArray, toptracks) {/**...*/};
//...
$(".tracks-container").innerHTML = renderTracks(parsed.toptracks.track, parsed.toptracks)
I hope this can help you :)
Your input JSON is not valid. You'll need to format it correctly. Once the data is correct:
createHTML.push(response.toptracks.track[0])
or
let i = 0;
for(; i < response.toptracks.track.length; i++){
createHTML.push(response.toptracks.track[i]);
}
Related
I am having many such entries in my json data. The "type" consists of tw attributes i.e. income and expense. How to print the "label" which have type="expense" in using JavaScript.
This json data below is just an example.
Check the image to get a better idea of json data.
"expenses_veterinary":{
label:"Veterinary, breeding, and medicine"
name:"expenses_veterinary"
total:0
type:"expense"
}
console.log($ctrl.gold_standard_categories); prints all the json data.
I tried the code written below but its not working.
if($ctrl.gold_standard_categories.name.type=expense){
console.log($ctrl.gold_standard_categories.label);
}
It prints all the data because of the single equals sign in your if statement.
It means you are always trying to assign the value "expense" to your type property and so the if statement will always evaluate to true.
What you are intending to do is compare the values, not assign a value.
https://jsfiddle.net/yxL4rpj2/
assume that in var money you store the json response
var grouppedMoney = {
expenses: [],
incomes: []
};
for(var i = 0; i <= money.length - 1; i++){
for(moneyType in money[i]){
var _typeString = money[i][moneyType].type == 'expense' ? 'expenses' : 'incomes';
grouppedMoney[_typeString].push(money[i][moneyType]);
}
}
Here is the basic example.Iterate over your object and see type value is equal to expense then print the label value.
var data = {
"expenses_veterinary":{
"label":"Veterinary, breeding, and medicine",
"name":"expenses_veterinary",
"total":0,
"type":"income"
},
"expenses_car":{
"label":"bus and truck",
"name":"expenses_car",
"total":0,
"type":"expense"
}
};
for (var property in data) {
if (data.hasOwnProperty(property)) {
// do stuff
if(data[property]['type']=='expense'){
console.log(data[property]['label']);
}
}
}
It seems you are using AngularJS ($ctrl) so you may consider using either native angular filters or custom filter to do this.
BTW, using vanilla JS, this simple loop will work :
for(var key in jsonData) {
if("expense" === jsonData[key]["type"]) {
console.log(jsonData[key]["label"]);
}
}
Sample snippet
var jsonData = {
"expensesigoods": {
"name": "expenses_goods",
"label": "Cost of goods sold",
"type": "expense",
"total": 0
},
"expensesicar": {
"name": "expenses_car",
"label": "Car and truck expenses",
"type": "expense",
"total": 0
},
"expensesichemicals": {
"name": "expenses_chemicals",
"label": "Chemicals",
"type": "expense",
"total": 0
},
"expensesiconservation": {
"name": "expenses_conservation",
"label": "Conservation expenses",
"type": "other",
"total": 0
}
}
for(var key in jsonData) {
if("expense" === jsonData[key]["type"]) {
console.log(jsonData[key]["label"]);
}
}
Try Array.filter() method to filter the data based on type="expense".
Working Fiddle
var obj = {
"expenses_goods":{
"label":"expenses_goods",
"name":"expenses goods",
"total":0,
"type":"income"
},
"expenses_cars":{
"label":"expenses_cars",
"name":"expenses cars",
"total":0,
"type":"expense"
},
"expenses_veterinary":{
"label":"expenses_veterinary",
"name":"expenses veterinary",
"total":0,
"type":"income"
}
};
var res = Object.keys(obj).filter(item => { return obj[item].type == 'expense' });
for (var i in res) {
document.getElementById("result").innerHTML = obj[res[i]].label;
}
<div id="result">
</div>
I really want to convert a object to array but my codes doesn’t worked.
data = "errors": {
"user": {
"name": "empty"
},
{
"length": "exceeds"
},
"title": {
"name": "empty"
},
{
"length": "exceeds"
}
}
Now I want to make them:
data = ["empty", "exceeds", "empty", "exceeds"];
What I’ve done so far is:
var arr = Object.keys(data[i].data.errors).map(function(k) {
return data[i].data.errors[k]
});
console.log(arr);
But the output is not what I expected. Please help. Thank very much.
If you always know the keys of the inner objects are going to be name and length a short way might be:
var out = Object.keys(data.errors).reduce(function (p, c) {
return p.concat([data.errors[c].name, data.errors[c].length]);
}, []);
DEMO
I have an JSON array like this
var filter_value_data = [{"Status":[{"name":"Open","id":"1"},{"name":"Pending","id":"2"},{"name":"Resolved","id":"3"},{"name":"Closed","id":"4"},{"name":"Evaluation","id":"5"}]},{"Payment Status":[{"name":"Paid","id":"10"},{"name":"UnPaid","id":"11"},{"name":"Part Paid","id":"12"}]},{"Priority":[{"name":"Low","id":"6"},{"name":"Medium","id":"7"},{"name":"High","id":"8"},{"name":"Urgent","id":"9"}]}]
I have tried filter_value_data["Status"] which is obviously wrong. How do I get the JSON elements for Status using the names like Status,Payment Status?
filter_value_data is an array (having []), so use filter_value_data[0].Status to get the first element-object with property "Status".
It is always good to format your code in order to see the hierarchy of the structures:
var filter_value_data = [
{
"Status": [
{
"name": "Open",
"id": "1"
}, {
"name": "Pending",
"id": "2"
}, ...
]
}, {
"Payment Status": [
{
"name": "Paid",
"id": "10"
}, ...
]
}, {
"Priority": [
{
"name": "Low",
"id": "6"
}, ...
]
}
];
With your current JSON you can't get the elements with the name alone.
You can get Status with filter_value_data[0]['Status'] and Payment status with filter_value_data[1]['Payment Status'].
This is because the keys are in seperate objects in the array.
In order to get them with filter_value_data['Status'] you need to change your JSON to
var filter_value_data = {
"Status":[
{"name":"Open","id":"1"},
{"name":"Pending","id":"2"},
{"name":"Resolved","id":"3"},
{"name":"Closed","id":"4"},
{"name":"Evaluation","id":"5"}
],
"Payment Status":[
{"name":"Paid","id":"10"},
{"name":"UnPaid","id":"11"},
{"name":"Part Paid","id":"12"}
],
"Priority":[
{"name":"Low","id":"6"},
{"name":"Medium","id":"7"},
{"name":"High","id":"8"},
{"name":"Urgent","id":"9"}
]
};
I wrote this on my phone so it's not as well-formatted as usual. I'll change it ASAP.
With your current JSON, created a result which might be helpful for you.
JS:
$.each(filter_value_data,function(ind,val){
var sta = val.Status; // Status Object get displayed
for(var i=0;i<sta.length;i++){
var idVal= sta[i].id;
var nameVal = sta[i].name;
Statusarray.push(idVal,nameVal);
console.log(Statusarray);
}
})
FiddleDemo
You can use below code, it will return status object
filter_value_data[0]['Status']
filter_value_data[0]['Payment Status']
to get Single value you use :
filter_value_data[0]['Status'][0]['name']
Let's say I have the next JSON file:
{
"shows": [
{
"name": "House of cards",
"rating": 8
},
{
"name": "Breaking bad",
"rating": 10
}
]
}
I want to access the rating of a show, by it's name. Something like this:
var rating = data.shows["House of cards"].rating;
Is this possible? Or something similar?
Thanks a lot!
You won't have such hash-style access just by deserializing that JSON sample.
Maybe you might be able to re-formulate how the data is serialized into JSON and use object literals even for shows:
{
"shows": {
"House of cards": {
"rating": 8
}
}
}
And you can still obtain an array of show keys using Object.keys(...):
Object.keys(x.shows);
Or you can even change the structure once you deserialize that JSON:
var x = { shows: {} };
for(var index in some.shows) {
x.shows[some.shows[index].name] = { rating: some.shows[index].rating };
}
// Accessing a show
var rating = x.shows["House of cards"].rating;
I suggest you that it should be better to do this conversion and gain the benefit of accessing your shows using plain JavaScript, rather than having to iterate the whole show array to find one.
When you use object literals, you're accessing properties like a dictionary/hash table, which makes no use of any search function behind the scenes.
Update
OP has concerns about how to iterate shows once it's an associative array/object instead of regular array:
Object.keys(shows).forEach(function(showTitle) {
// Do stuff here for each iteration
});
Or...
for(var showTitle in shows) {
// Do stuff here for each iteration
}
Update 2
Here's a working sample on jsFiddle: http://jsfiddle.net/dst4U/
Try
var rating = {
"shows": [
{
"name": "House of cards",
"rating": 8
},
{
"name": "Breaking bad",
"rating": 10
}
]
};
rating.shows.forEach(findsearchkey);
function findsearchkey(element, index, array) {
if( element.name == 'House of cards' ) {
console.log( array[index].rating );
}
}
Fiddle
var data = {"shows": [{"name": "House of cards","rating": 8},{"name": "Breaking bad","rating": 10}]};
var shows = data.shows;
var showOfRatingToBeFound = "House of cards";
for(var a in shows){
if(shows[a].name == showOfRatingToBeFound){
alert("Rating Of "+ showOfRatingToBeFound+ " is " +shows[a].rating);
}
}
I have a json tree structure that is appended to by pressing invoke on this fiddle : http://jsfiddle.net/adrianjsfiddlenetuser/C6Ssa/4/
Press invoke multiple tiles on the fiddle & copy/paste the produced jSon intohttp://jsonlint.com/, the produced json is not valid
I need to produce this :
{
"nodes": [
{
"url": "asdfas",
"date": ""
},
{
"url": "asdfas",
"date": ""
},
{
"url": "asdfasfdasas",
"date": ""
}
]
}
Can this be amended so that multiple children can be added to the tree structure, I think I need to amend the var data somehow ?
Try:
var data = {nodes: []};
$("#add").on('click', function () {
data.nodes.push({
url: "some url",
date: new Date
});
$("#myDiv").text(JSON.stringify(data));
});
if not, I didn't understand your question ;)
http://jsfiddle.net/gY5yQ/
See if this helps http://jsfiddle.net/C6Ssa/12/
var data = [];
$("#add").click(add);
function add() {
data.push({
param1: "stuff",
param2:1,
param3:1
});
var sample = {};
sample.node = data
$("#myDiv").text(JSON.stringify(sample));
}