How to put multiple GET's in an array with jQuery - javascript

How do I put multiple GET's in an array?
I want to start with putting all channelId's in an array like this:
var Channels = [ID1, ID2, ID3];
And then a function with $each... But how to do it? :)
Who can help me please? It will be much appreciated
var ItemArray = [];
var d1 = $.get("https://www.googleapis.com/youtube/v3/search?channelId=UCVQ2Z9dNQ2aJJ10f6SgBH0g&type=video&order=date&maxResults=1&part=snippet&KEY",
function (data) {
$.each(data.items, function (i, item) {
idee = item.id.videoId;
tittie = item.snippet.title;
cattit = item.snippet.channelTitle;
datie = item.snippet.publishedAt;
ItemArray.push([datie, cattit, idee, tittie]);
});
});
var d2 = $.get("https://www.googleapis.com/youtube/v3/search?channelId=UC2xskkQVFEpLcGFnNSLQY0A&type=video&order=date&maxResults=1&part=snippet&KEY",
function (data) {
$.each(data.items, function (i, item) {
idee = item.id.videoId;
tittie = item.snippet.title;
cattit = item.snippet.channelTitle;
datie = item.snippet.publishedAt;
ItemArray.push([datie, cattit, idee, tittie]);
});
});
var d3 = $.get("https://www.googleapis.com/youtube/v3/search?channelId=UCGHi_s4RrqUh4hsS4mLbiPg&type=video&order=date&maxResults=1&part=snippet&key=KEY",
function (data) {
$.each(data.items, function (i, item) {
idee = item.id.videoId;
tittie = item.snippet.title;
cattit = item.snippet.channelTitle;
datie = item.snippet.publishedAt;
ItemArray.push([datie, cattit, idee, tittie]);
});
});
$.when(d1, d2, d3).done(function() {
ItemArray.sort(function(a, b) {
return a[0] - b[0];
});
for(i=0;i<=ItemArray.length;i++){
$('#mytable').append('<tr><td>'+ItemArray[i][0]+'</td><td><a target="_blank" href="https://www.youtube.com/user/'+ItemArray[i][1]+'">'+ItemArray[i][1]+'</a></td><td><a target="_blank" href="https://www.youtube.com/watch?v='+ItemArray[i][2]+'">'+ItemArray[i][3]+'</a></td></tr>');
}
})
})

See example below.
The code is commented an should work as expected.
Ask if any questions.
(function($) {
var ItemArray = [];
// List all IDs here
var ids = ["UCVQ2Z9dNQ2aJJ10f6SgBH0g", "UC2xskkQVFEpLcGFnNSLQY0A", "UCGHi_s4RrqUh4hsS4mLbiPg"];
var done = [];
// Go through all ids
$.each(ids, function(index, value) {
// Save all Deferred in variable done
done.push($.get("https://www.googleapis.com/youtube/v3/search?channelId=" + value + "&type=video&order=date&maxResults=1&part=snippet&KEY", fn)); // use function fn for doing all the time the same
});
function fn(data) {
$.each(data.items, function(i, item) {
idee = item.id.videoId;
tittie = item.snippet.title;
cattit = item.snippet.channelTitle;
datie = item.snippet.publishedAt;
ItemArray.push([datie, cattit, idee, tittie]);
});
}
// to use an array as input for when()
// you need th use the prototype method apply to convert it
$.when.apply($, done).done(function() {
// this part stays the same
ItemArray.sort(function(a, b) {
return a[0] - b[0];
});
for (i = 0; i <= ItemArray.length; i++) {
$('#mytable').append('<tr><td>' + ItemArray[i][0] + '</td><td><a target="_blank" href="https://www.youtube.com/user/' + ItemArray[i][1] + '">' + ItemArray[i][1] + '</a></td><td><a target="_blank" href="https://www.youtube.com/watch?v=' + ItemArray[i][2] + '">' + ItemArray[i][3] + '</a></td></tr>');
}
});
})(jQuery);

So loop over the array and make the ajax calls, pushing the Ajax calls into a new array.
var channels = ["a","b","c"],
calls = channels.reduce( function (arr, current) {
var xhr = $.get("http://example.com?q=" + current, function() { /* your code ajax success*/});
arr.push(xhr);
return arr;
}, []);
//Take that array and apply it to the when
$.when.apply($, calls).done( function () {
//Your code
} )

Related

Delete duplicate object(JSON) nodes - JavaScript

I have a JSON string:
var jsn = '{"header-v1":{"archives":{"is_author":"all"}},"header-v4":{"archives":{"is_author":"all"}}}';
This object is constantly updated and I want to remove duplicate values. For example, if it is:
var jsn = '{"header-v4":{"archives":{"is_author":"all"}}}';
And if the new rule set which should be added will be equal to
"header-v1":{"archives":{"is_author":"all"}}
then I want to remove "header-v4":{"archives":{"is_author":"all"}} from there, because there is a duplicate of {"archives":{"is_author":"all"}}.
Is that even possible with JavaScript?
var result = [];
$.each(subservices, function (i, e) {
var matchingItems = $.grep(result, function (item) {
return item.name === e.name && item.label === e.label;
});
if (matchingItems.length === 0){
result.push(e);
}
});
//displays result [{"name":"hello","label":"world"},{"name":"abc","label":"xyz"}]
alert(JSON.stringify(result));
JS fiddel
http://jsfiddle.net/defujjhp/
Maybe something like this you can do
var jsn = '{"header-v4":{"archives":{"is_author":"all"}}}';
var jsonObject = JSON.parse(jsn);
var newJsn = '{header-v1":{"archives":{"is_author":"all"}}}';
var newJsonObject = JSON.parse(newJsn);
var matchingKey = [];
Object.keys(newJsonObject).forEach(key => {
Object.keys(jsonObject).forEach(nkey => {
if(newJsonObject[key].toString() === jsonObject[nkey].toString()) {
matchingKey.push(nkey);
}
});
});
matchingKey.forEach(mkey => {
delete jsonObject[mkey];
});

Array length remains 0 even though I push 'objects' to it

I have a little piece of code that reads some ajax (this bit works) from a server.
var self = this;
var serverItems = new Array();
var playersOnlineElement = $("#playersOnline");
function DataPair(k, v) {
this.key = k;
console.log("new datapair: " + k + ", " + v);
this.value = v;
}
DataPair.prototype.getKey = function() {
return this.key;
}
DataPair.prototype.getValue = function() {
return this.value;
}
$.getJSON("http://127.0.0.1", function(data) {
$.each(data, function(key, val) {
var pair = new DataPair(key, val);
self.serverItems.push(pair);
});
});
console.log(serverItems.length); //Problem is here
for (var i = 0; i < serverItems.length; i = i + 1) {
var dpair = serverItems[i];
if (dpair.getKey() === "playersOnline") {
self.playersOnlineElement.text("Players Online: " + dpair.getValue());
}
}
The datapair and the JSON get loaded but when they are pushed to the array it doesn't seem to work. I tried with self.serverItems and just serverItems because netbeans showed me the scope of the variables being good if I used just serverItems but I am a bit confused as to why this doesn't work. Can anyone help me?
I put in comments where the error is. serverItems.length is 0 even though when debugging in a browser in the DOM tree it has an array serverItems with all the data inside.
Assumingly this serverItems is in another scope and not the one I am calling when I want to get the length?
add this code into the success part, since its asynchronous...
for (var i = 0; i < serverItems.length; i = i + 1) {
var dpair = serverItems[i];
if (dpair.getKey() === "playersOnline") {
self.playersOnlineElement.text("Players Online: " + dpair.getValue());
}
to...
$.getJSON("http://127.0.0.1", function(data) {
$.each(data, function(key, val) {
var pair = new DataPair(key, val);
self.serverItems.push(pair);
for (var i = 0; i < serverItems.length; i = i + 1) {
var dpair = serverItems[i];
if (dpair.getKey() === "playersOnline") {
self.playersOnlineElement.text("Players Online: " + dpair.getValue());
}
});
});

How to count duplicate array elements? (javascript)

I'm trying to make an XML based menu with JavaScript, XML and jQuery. I've been successful at getting the categories of the menu, but haven't been able to generate the items in the categories.
My script is as follows, and later in this thread, I've asked for suggestions for this code:
var animalsXMLurl = 'http://dl.dropboxusercontent.com/u/27854284/Stuff/Online/XML_animals.xml';
$(function() {
$.ajax({
url: animalsXMLurl, // name of file you want to parse
dataType: "xml",
success: function parse(xmlResponse) {
var data = $("item", xmlResponse).map(function() {
return {
id: $("animal_id", this).text(),
title: $("animal_title", this).text(),
url: $("animal_url", this).text(),
category: $("animal_category", this).text().split('/'),
};
}).get();
var first_item = category_gen(data, 0);
$('ul.w-nav-list.level_2').append(first_item);
var categnumber = new Array();
for (i = 1; i <= data.length; i++) //for splitting id, and getting 0 for category_number (1 or 2 or 3...and so on)
{
categnumber[i] = data[i].id.split('_');
console.log(categnumber[i][0]);
for (j = 1; j <= data.length; j++) //appending via a function.
{
var data_text = category_or_animal(data, categnumber, j);
console.log(data_text);
$('ul.w-nav-list.level_2').append(data_text);
}
}
function category_or_animal(d, catg, k) {
var catg1 = new Array();
var catg2 = new Array();
var catg1 = d[k].id.split('_');
if (d[k - 1]) {
var catg2 = d[k - 1].id.split('_');
//if(d[k-1].id)
if (catg1[0] != catg2[0])
return category_gen(d, k);
} else
return '</ul>' + animal_gen(d, k);
}
function category_gen(d, z) {
var category_var = '<li class="w-nav-item level_2 has_sublevel"><a class="w-nav-anchor level_2" href="javascript:void(0);"><span class="w-nav-title">' + d[z].category + '</span><span class="w-nav-arrow"></span></a><ul class="w-nav-list level_3">';
return category_var;
}
function animal_gen(d, z) {
var animal_var = '<li class="w-nav-item level_3"><a class="w-nav-anchor level_3" href="animals/' + d[z].url + '"><span class="w-nav-title">' + d[z].title + '</span><span class="w-nav-arrow"></span></a></li>';
return animal_var;
}
}, error: function() {
console.log('Error: Animals info xml could not be loaded.');
}
});
});
Here's the JSFiddle link for the above code: http://jsfiddle.net/mohitk117/d7XmQ/4/
In the above code I need some alterations, with which I think the code might work, so I'm asking for suggestions:
Here's the function that's calling separate functions with arguments to generate the menu in above code:
function category_or_animal(d, catg, k) {
var catg1 = new Array();
var catg2 = new Array();
var catg1 = d[k].id.split('_');
if (d[k - 1]) {
var catg2 = d[k - 1].id.split('_');
//if(d[k-1].id)
if (catg1[0] != catg2[0])
return category_gen(d, k);
} else
return animal_gen(d, k) + '</ul>';
}
At the if(catg1[0] != catg2[0]) it checks if the split string 1_2 or 1_3 is equal to 1_1 or 1_2 respectively. By split, I mean the first element: 1 .... if you have a look at the xml: [ :: Animals XML :: ], you'll see that the animal_id is in the format of %category_number% _ %item_number% ... So I need to create the menu with CATEGORY > ITEM (item=animal name)
Now if I could return category_gen() + animal() with animal(){ in a for loop for all the matching category id numbers} then maybe this could be complete! But I don't of a count script for conditioning the for loop (i=0;i<=count();i++)...
Would anyone know of how to get this script functioning?
Hard to tell what the provided JSFiddle is trying to do.
This is my best stab at it. I used JQuery to parse the XML out into categories and generate lists of items.
http://jsfiddle.net/d7XmQ/8/
"use strict";
var animalsXMLurl = 'http://dl.dropboxusercontent.com/u/27854284/Stuff/Online/XML_animals.xml';
$(function () {
var $menu = $('#menu');
$.ajax({
url: animalsXMLurl, // name of file you want to parse
dataType: "xml",
success: handleResponse,
error: function () {
console.log('Error: Animals info xml could not be loaded.');
}
});
function handleResponse(xmlResponse) {
var $data = parseResponse(xmlResponse);
createMenu($data);
}
function parseResponse(xmlResponse) {
return $("item", xmlResponse).map(function () {
var $this = $(this);
return {
id: $this.find("animal_id").text(),
title: $this.find("animal_title").text(),
url: $this.find("animal_url").text(),
category: $this.find("animal_category").text()
};
});
}
function createMenu($data) {
var categories = {};
$data.each(function (i, dataItem) {
if (typeof categories[dataItem.category] === 'undefined') {
categories[dataItem.category] = [];
}
categories[dataItem.category].push(dataItem);
});
$.each(categories, function (category, categoryItems) {
var categoryItems = categories[category];
$menu.append($('<h2>').text(category));
$menu.append(createList(categoryItems));
});
}
function createList(categoryItems) {
var $list = $('<ul>');
$.each(categoryItems, function (i, dataItem) {
$list.append(createItem(dataItem));
});
return $list;
}
function createItem(dataItem) {
return $('<li>').text(dataItem.title);
}
});
You can solve this without using any for/while loop or forEach.
function myCounter(inputWords) {
return inputWords.reduce( (countWords, word) => {
countWords[word] = ++countWords[word] || 1;
return countWords;
}, {});
}
Hope it helps you!

Bizarre Array Mirroring Issue

I have two arrays, both of which get populated by data from a post request.
The purpose of this is so that when alterations are made to the "live" array, they are compared to the "original" array so changes can be spotted.
Here is my post:
$('#dialogs').load('views/Products/managePicsDialog.php', function(){
var imageArray = [];
var originalImageArray = [];
$('#managePicsDialog').modal();
productId = 1;
$.post(ROOT+'products/fetch-thumbnails', 'pid='+productId, function(data){
imageArray = originalImageArray = data;
nextPriority = imageArray.length+1;
renderImageList(imageArray);
}, 'json')
...
Initially I thought this would be fine, data gets put into imageArray and originalImageArray.
Throughout my code originalImageArray doesn't get touched at all, only imageArray gets manipulated and changed.
Now when it comes to comparing the arrays, it seems originalImageArray copies imageArray on every change which I do not understand why:
function saveChanges(imageArray, originalImageArray)
{
$.each(originalImageArray, function(i, obj){
$.each(obj, function(i2, v){
if(imageArray[i][i2] != v)
{
alert('changed') // Never happens
}
})
})
}
If I "alert each" both arrays the values are clearly shown to copy each other, even though there is no where in my code that states originalImageArray = imageArray except in my $.post method which only gets called once when the dialog is opened.
Can anyone solve this for me?
The contents of the arrays are objects.
Here is the full code to help clarify:
$('#productGrid').on('click', '#managePics', function(e){ // When managepics option is clicked
e.preventDefault(); // Don't go to the hyperlink...
closeMenu(); // Close the popup menu...
$('#dialogs').load('views/Products/managePicsDialog.php', function(){
var imageArray = [];
var originalImageArray = [];
$('#managePicsDialog').modal();
productId = 1;
$.post(ROOT+'products/fetch-thumbnails', 'pid='+productId, function(data){
imageArray = data;
originalImageArray = data.slice(0);
nextPriority = imageArray.length+1;
renderImageList(imageArray);
}, 'json')
$('#fileUpload').fileupload({
url: ROOT+'UploadHandler',
process: [
{
maxFileSize: 2000000000
}
],
progressInterval: 50,
add: function(e, data)
{
data.submit();
},
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .bar').css('width', progress + '%').html(progress+'%');
},
done: function(e, data)
{
n = $.parseJSON(data.result)
pushed = {
"id": "0",
"priority": nextPriority,
"thumb": n.files[0].thumbnail_url,
"deleted": 0
}
imageArray.push(pushed);
renderImageList(imageArray);
}
});
$('#thumbnails').on('click', 'button.delete', function(e){
$(this).closest('.span8').fadeOut('fast', function(){
$(this).detach();
});
idx = $(this).closest('.span8').data('index');
deleteImage(imageArray, idx)
})
$('#managePicsDialog').on('click', '.move-down:not(.disabled)', function(){
idx = $(this).closest('.span8').data('index');
if(imageArray[idx+1])
{
temp = imageArray[idx+1];
imageArray[idx+1] = imageArray[idx];
} else {
temp = imageArray[0];
imageArray[0] = imageArray[idx];
}
imageArray[idx] = temp;
renderImageList(imageArray)
})
$('#managePicsDialog').on('click', '.move-up:not(.disabled)', function(){
idx = $(this).closest('.span8').data('index');
if(imageArray[idx-1])
{
temp = imageArray[idx-1];
imageArray[idx-1] = imageArray[idx];
} else {
temp = imageArray[imageArray.length-1];
imageArray[imageArray.length-1] = imageArray[idx];
}
imageArray[idx] = temp;
renderImageList(imageArray)
})
$('#cancelChanges').click(cancelChanges)
$('#saveChanges').click(function(){
saveChanges(imageArray, originalImageArray)
})
})// Close dialog
})
function saveChanges(imageArray, originalImageArray)
{
// commitChanges(imageArray)
$.each(originalImageArray, function(i, obj){
$.each(obj, function(i2, v){
alert(i2+' => '+v)
})
})
$.each(imageArray, function(i, obj){
$.each(obj, function(i2, v){
alert(i2+' => '+v)
})
})
$.each(originalImageArray, function(i, obj){
$.each(obj, function(i2, v){
if(imageArray[i][i2] != v)
{
alert('changed')
}
})
})
}
function deleteImage(imageArray, index)
{
if(imageArray[index].id == 0) // If is a new image we just remove it from array.
{
imageArray.splice(index, 1);
} else { // If existing image we mark it for deletion.
imageArray[index].deleted = 1;
}
renderImageList(imageArray);
}
function renderImageList(imageArray)
{
var thumbHTML = '';
$.each(imageArray, function(i, v){
if(v.deleted == 0)
{
thumbHTML += '<div class="span8 well" data-index="'+i+'">';
thumbHTML += '<div class="span2">';
thumbHTML += '<img src="images/'+v.thumb+'" height="" width="" class="last-added">';
thumbHTML += '</div>';
thumbHTML += '<div class="span4">';
thumbHTML += '</div>';
thumbHTML += '<div class="span1">';
thumbHTML += '<button class="btn btn-info btn-100 move-up">Move up</button>';
thumbHTML += '<button class="btn btn-info btn-100 move-down">Move down</button>';
thumbHTML += '<button class="btn btn-danger btn-100 delete">Remove</button>';
thumbHTML += '</div>';
thumbHTML += '</div>';
}
})
$('#thumbnails').html(thumbHTML);
}
You need to clone it so they do not share the same reference
imageArray = data;
originalImageArray = data.slice(0);

Return a value with jQuery each() function

i'm new to javascript, and I would like to retrieve values from JSON and push it into an array so that I can parse again this array in another function, But I don't know how to return the array after pushing element inside it.
In the following script I can't display values in items
function gC(b,c,p) {
$.getJSON('getmonths', 'b='+b+'&c='+c+'&p='+p, processJSON);
}
function processJSON(data) {
var retval = [];
$.each(data, function(key, val) {
retval.push(val);
//alert(retval.pop());
});
return retval;
}
$(document).ready(function(){
var b = $("#b").val();
var c = $("#c").val();
var p = $("#p").val();
var items = [];
items = gC(b,c,p);
var i = 0;
$('td').each(function(index) {
$(this).attr('bgcolor', items[i]);
i++;
}
How could I access the array ?
thank !
You don't return from an AJAX call, you have it call a callback function when it's done.
function gC(b,c,p) {
var retval = [];
$.getJSON('getmonths', 'b='+b+'&c='+c+'&p='+p, processData);
}
function processData(data){
var retval = [];
$.each(data, function(key, val) {
retval.push(val);
//alert(retval.pop());
});
alert(retval);
}
processData would be called when the AJAX call is done. This can't return a value to another function, so all your logic has to be inside this callback function.
UPDATE: You can also pass in a callback function to gC to be called when it's done.
function gC(b,c,p,f) {
var retval = [];
$.getJSON('getmonths', 'b='+b+'&c='+c+'&p='+p, function(d){
if(typeof f == 'function'){
f(d);
}
});
}
Then you call gC like so:
gC(b,c,p,function(data){
var retval = [];
$.each(data, function(key, val) {
retval.push(val);
//alert(retval.pop());
});
alert(retval);
});
UPDATE2: I saw the code you added to the question. This needs to be done in the callback.
gC(b,c,p,function(data){
var items = [];
$.each(data, function(key, val) {
items.push(val);
});
$('td').each(function(index){ // You don't need a separate i variable
// you can just use the index from the loop
$(this).attr('bgcolor', items[index]);
}
})
Just have the code inside the callback:
function processJSON(data) {
var retval = [];
$.each(data, function(key, val) {
retval.push(val);
});
$('td').each(function(index) {
if (index < retval.length)
$(this).attr('bgcolor', retval[index]);
});
}

Categories

Resources