How to dynamically grab a value using jquery for each? - javascript

So i've been stuck trying to figure this out. I'm pretty sure I'm lacking a key piece of information. I'm grabbing some values from a JSON response. One contains a list of names. Another contains a list of URLs that correspond to the list of Names.
For instance:
{"names":"john,casey,davey",
"nameUrls":[{
"johnURL":"http://url.com",
"caseyURL":"http://url.com",
"daveyURL":"http://url.com"]}
names = (data.names).split(',');
$.each(data.nameUrls, function(key, val) {
for (var i = 0; i < names.length; i++) {
$("#left").append(val[names[i] + "URL"]);
}
})
Now the first one comes through just fine. But the rest come in undefined. So what am I doing wrong? Thanks in advance for your help.
Edit: Adding more code.

After fixing some syntax errors, here's the code which I tested in console and it's working.
var data = {
"names": "john,casey,davey",
"nameUrls": {
"johnURL": "http://url.com",
"caseyURL": "http://url.com",
"daveyURL": "http://url.com"
}
};
names = (data.names).split(',');
$.each(data.nameUrls, function (key, val) {
for (var i = 0; i < names.length; i++) {
$("#left").append(val[names[i] + "URL"]);
}
});
In above lines, I just fixed the syntax errors, however I believe this might not let you achieve what you want. Try the below code and let me know.
var data = {
"names": "john,casey,davey",
"nameUrls": {
"johnURL": "http://url1.com",
"caseyURL": "http://url2.com",
"daveyURL": "http://url3.com"
}
};
names = (data.names).split(',');
$.each(data.nameUrls, function (key, val) {
$("#left").append(val);
});

It seems to me like you should restructure your data so that there is an easier association amongst it.
Would something like this work for you?
data = [
{"name": "john", "url": "http://url.com"},
{"name": "casey", "url": "http://url.com"},
{"name": "davey", "url": "http://url.com"}
];
$.each(data, function(index, person) {
$('#left').append(person.url);
});

var data = {
"names": "john,casey,davey",
"nameUrls": {
"johnURL": "http://url.com",
"caseyURL": "http://url.com",
"daveyURL": "http://url.com"
}
};
$.each(data.names.split(','), function (i, v) {
$("#left").append( v + " ==> " + data.nameUrls[v + 'URL'] );
});

Related

How can get a count with nested objects with a certain property?

Okay so I'm using angular to get a json saved to my computer to recreate a github gradebook.
I can get the data with my $http request but for the love of me all I want is to get a count of the number of issues with the label "Not Yet".
Here is the javascript:
$http.get('/api/github/repos/issues/all_issues/00All.json')
.then(function(response) {
console.log(response.data[0]);
var counter = 0;
for(var index = 0; index < response.data.length; index++) {
if(response.data[index].labels[0].name == "Not Yet") {
counter++;
};
};
console.log(counter);
});
That's the latest try, I also tried using lodash to get it earlier:
$http.get('/api/github/repos/issues/all_issues/00All.json')
.then(function(response) {
console.log(response);
mile.notYet.width = _.forEach(response.data, function(n){
var counter = 0;
if(_.result(_.find(n.labels[0], 'name')) == "Not Yet") {
counter++;
}
console.log(counter);
counter = ((counter/10) * 100) + '%';
});
});
This is a bit of the json data:
[
{
"url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11",
"labels_url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11/labels{/name}",
"comments_url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11/comments",
"events_url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11/events",
"html_url": "https://github.com/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11",
"id": 73013825,
"number": 11,
"title": "00 -- Brace Yourself -- BEN GRIFFITH",
"user": {
"login": "Epicurean306",
"id": 11682684,
"avatar_url": "https://avatars.githubusercontent.com/u/11682684?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/Epicurean306",
"html_url": "https://github.com/Epicurean306",
"followers_url": "https://api.github.com/users/Epicurean306/followers",
"following_url": "https://api.github.com/users/Epicurean306/following{/other_user}",
"gists_url": "https://api.github.com/users/Epicurean306/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Epicurean306/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Epicurean306/subscriptions",
"organizations_url": "https://api.github.com/users/Epicurean306/orgs",
"repos_url": "https://api.github.com/users/Epicurean306/repos",
"events_url": "https://api.github.com/users/Epicurean306/events{/privacy}",
"received_events_url": "https://api.github.com/users/Epicurean306/received_events",
"type": "User",
"site_admin": false
},
"labels": [
{
"url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/labels/Not%20Yet",
"name": "Not Yet",
"color": "e11d21"
}
],
As you can see the labels property is an object, nested in an array, nested in an object, nested in an array, real lovely. Putting labels[0] results in an error for me each time and doesn't get me a count. Can anybody tell me where I'm messing up please? Thank you!
If you need a solution that includes lodash, which is much more performant than the native high order functions then you can try this solution below:
var size = _(response.data)
.pluck('labels')
.flatten()
.where({ name: 'Not Yet' })
.size();
UPDATE:
If you want it to be more reusable, you can save a reference for a cloned chained sequence and simply supply another array for that cloned sequence.
var data1 = [/*array from data1*/];
var data2 = [/*array from data2*/];
var notYetSequence = _(data1)
.pluck('labels')
.flatten()
.where({ name: 'Not Yet' });
notYetSequence.size(); // returns data 1 count
notYetSequence.plant(data2).size(); // returns data 2 count
You don't need lodash for the task
var cnt = response.data
.map(function(i) { return i.labels; })
// here we extract labels object only (and get an array of arrays of objects)
.map(function(i) { return i.filter(function(l) { return l.name == 'Not yet'; }).length; })
// then for every nested array we return a number of items with
// Not Yet names (and get an array of numbers)
.filter(function(c) { return c > 0; })
// then we filter issues that don't have one (and still get an array of numbers)
.length;
// and finally get length (which is a number)
As a comparison, a plain for loop looks like:
var data = response.data;
var count = 0;
var re = /not yet/i;
for (var a, i=0, iLen=data.length; i<iLen; i++) {
a = data[i].labels;
for (var j=0, jLen=a.length; j<jLen; j++) {
if (re.test(a[j].name)) ++count;
}
}
So really not a lot of code either way, the for loop will be compatible with every browser ever (though using xmlHTTPRequest means at least ed 3+) and fastest… untested of course. ;-)

Node Mongoose and Q Promises

I'm trying to wrap my brain around promises and I'm refactoring some nested callbacks into promises. I'm encountering something I don't understand and any help anyone could provide would be appreciated. There's definitely something wrong with my for-loop; I suppose that sort of structure is invalid but I'm not sure what to do about it. Also, the result coming back from insertTickersDb function appears to take my entire array and insert it as a single record - not what I was hoping for. I know I'm doing things wrong - please help me understand which things.
I have bound a function to mongoose like this:
var insertTickersDb = q.nfbind(db.tickers.insert.bind(db.tickers));
I have an insert function that looks like this:
function insertTickers(symbols) {
console.log("inserting tickers");
if (symbols) {
if (!(symbols instanceof Array)) {
symbols = [symbols];
}
var tickersToInsert = [];
symbols.map(function(symbol) {
tickersToInsert.push({
symbol: symbol
});
});
console.log("tickersToInsert = " + JSON.stringify(tickersToInsert));
return insertTickersDb(tickersToInsert);
}
}
and I have a test like this:
describe("tickerIntegrationTests internal testing tools", function() {
it("insertTickers should insert the provided tickers", function(done) {
var tickerList = ["A", "B", "C"];
insertTickers(tickerList).then(function(data) {
console.log("inside insertTickers, data = " + JSON.stringify(data));
for (var d = 0; d < data.length; d++) {
console.log("d = " + d + ",data[d].symbol = " + data[d].symbol);
assert.equal(data[d].symbol, tickerList[d]);
}
}).then(removeTickers(tickerList)).done(function(){done();});
});
});
My output is:
tickerIntegrationTests internal testing tools
inserting tickers
tickersToInsert = [{"symbol":"A"},{"symbol":"B"},{"symbol":"C"}]
inside insertTickers, data = [[{"symbol":"A","_id":"552faf5c0aac9578428320da"},{"symbol":"B","_id":"552faf5c0aac9578428320db"},{"symbol":"C","_id":"552faf5c0aac9578428320dc"}],{"n":0}]
d = 0,data[d].symbol = undefined
It might help if you expand out the json of the inner call
[
[
{
"symbol": "A",
"_id": "552faf5c0aac9578428320da"
},
{
"symbol": "B",
"_id": "552faf5c0aac9578428320db"
},
{
"symbol": "C",
"_id": "552faf5c0aac9578428320dc"
}
],
{
"n": 0
}
]
Now you can see the the data is an array whose first element is the data array you are expecting. If you looked at data[0] you would find the first ticker. d[0].symbol should contain what you are looking for. You might want to look at t

javascript: get index of object from dictonary key

my data array
data : [
{
"name": "Autauga, AL",
"value": 5.6
},
{
"name": "Baldwin, AL",
"value": 5.3
},...
]
How can I retrieve the index of an array object if I just have the name "Autauga, AL"?
I am aware of the brute force loops. is there a better way?
In ECMAScript 5.1+, you can use the Array#filter method to get the actual object:
data.filter(function(item){return item.name == 'Autauga, AL'})[0]
That doesn't get you the index, though. You could do this:
data.map(function(item,index){
return [item, index]
}).filter(function(a){
return a[0].name == 'Autauga, AL'
})[0][1]
Those methods still wind up using loops under the covers, but I guess they look cooler..
For efficient access, you could build an index for the target field:
var dataIndexByName = {}, i, len;
for (i=0, len=data.length; i<len; ++i) {
dataIndexByName[data[i].name] = i
}
After which you can just look for dataIndexByName['Autauga, AL']. That also has the advantage of working in older implementations. It gets a bit more complicated if a given name might show up more than once in the original array, though.
You could do something like this:
for (var i = 0, len = data.length; i++) {
if (data[i].name.indexOf("Autauga, AL") > -1) {
return i;
}
}
You could write a small function to do the job based on Array.prototype.some:
function getIndex(arr, prop, value) {
var idx;
arr.some(function(v, i) {
if (v[prop] == value) {
idx = i;
return true;
}
});
return idx;
}
data = [{"name": "Autauga, AL","value": 5.6},
{"name": "Baldwin, AL","value": 5.3}];
console.log(getIndex(data, 'name', 'Baldwin, AL')); // 1
some is efficient because it stops when the callback first returns true. You may wisht to adjust the condition to suit.

Syntax for parsing the Nth item from JSON array using JQuery

I've seen many JQuery examples that make use of $.each to loop through a JSON array. However, what need to do is individually grab items 0 - 3 and pass them to another function called "Search". Here's what I've come up with.
$.getJSON("http://localhost:61741/binggame/play?cat=Body%20Parts", {
tags: "English",
tagmode: "any",
format: "json"
},
function (data) {
Search(data.items[0], "Box1_Image");
Search(data.items[1], "Box2_Image");
Search(data.items[2], "Box3_Image");
Search(data.items[3], "Box4_Image");
});
I'm fairly certain that data.items[] is not the correct syntax.
Here's a sample of my JSON:
{"nouns":[
{
"ID":26,
"Category":"Body Parts",
"English":"muscle",
"Pinyin":"gei yUk",
"Image1":null,
"Audio1":null
},
{
"ID":27,
"Category":"Body Parts",
"English":"neck",
"Pinyin":"gen",
"Image1":null,
"Audio1":null
},
{
"ID":28,
"Category":"Body Parts",
"English":"nose",
"Pinyin":"bei",
"Image1":null,
"Audio1":null
},
{
"ID":29,
"Category":"Body Parts",
"English":"rib",
"Pinyin":"lat gwt",
"Image1":null,
"Audio1":null
}
]}
For this sample, the value of data.items[0] should be "muscle", data.items[1] should be "neck", data.items[2] should be "nose" and data.items[3] should be "rib".
Can someone point out to me what I've done wrong?
Can someone point out to me what I've done wrong?
To start, there is no property names items in your JSON.
If you want to get "muscle": data.nouns[0].English
If you want to get "neck": data.nouns[1].English
and so on:
function (data) {
Search(data.nouns[0].English, "Box1_Image");
Search(data.nouns[1].English, "Box2_Image");
Search(data.nouns[2].English, "Box3_Image");
Search(data.nouns[3].English, "Box4_Image");
});
or, to stay DRYer:
function (data) {
var nouns = data.nouns;
function getNoun(i) {
return nouns[i].English;
}
Search(getNoun(0), "Box1_Image");
Search(getNoun(1), "Box2_Image");
Search(getNoun(2), "Box3_Image");
Search(getNoun(3), "Box4_Image");
});
or better still:
function (data) {
var nouns = data.nouns;
for (var i=0; i<4; i++) {
Search(nouns[i].English, 'Box' + (i+1) + '_Image');
}
});
I assume you are manipulating the list in the nouns property and in that case it would be:
for (var i = 0, l = data.nouns.length; i < l; i++) {
Search(data.nouns[i].English, 'Box' + (i + 1) + '_Image');
}

how to get distinct values from json in jquery

I've got a jquery json request and in that json data I want to be able to sort by unique values. so I have
{
"people": [{
"pbid": "626",
"birthDate": "1976-02-06",
"name": 'name'
}, {
"pbid": "648",
"birthDate": "1987-05-22",
"name": 'name'
}, .....
So, far, i have this
function(data) {
$.each(data.people, function(i, person) {
alert(person.birthDate);
})
}
but, I am at a total loss as to how efficiently get only the unique birthDates, and sort them by year (or any sort by any other personal data).
I'm trying to do this, and be efficient about it (i'm hoping that is possible).
Thanks
I'm not sure how performant this will be, but basically I'm using an object as a key/value dictionary. I haven't tested this, but this should be sorted in the loop.
function(data) {
var birthDates = {};
var param = "birthDate"
$.each(data.people, function() {
if (!birthDates[this[param]])
birthDates[this[param]] = [];
birthDates[this[param]].push(this);
});
for(var d in birthDates) {
// add d to array here
// or do something with d
// birthDates[d] is the array of people
}
}
function(data){
var arr = new Array();
$.each(data.people, function(i, person){
if (jQuery.inArray(person.birthDate, arr) === -1) {
alert(person.birthDate);
arr.push(person.birthDate);
}
});
}
Here's my take:
function getUniqueBirthdays(data){
var birthdays = [];
$.each(data.people, function(){
if ($.inArray(this.birthDate,birthdays) === -1) {
birthdays.push(this.birthDate);
}
});
return birthdays.sort();
}

Categories