How to store JSON data from two sources in javascript objects when the data is pulled in at different rates?
-
21-12-2019 - |
Question
I am trying to create Article
objects from links pulled in with ajax (using the jquery reddit api) combined with extra information about the links (pulled in from the embed.ly jquery api).
The Article
objects (containing data from the reddit api) are stored in an array called articles
using the push method to preserve the order of the links. I am using the same i
value to iterate through both the reddit data and to dictate in which Article
within in the articles
array to store the embed.ly data. This is because I was having problems with the embed.ly data being stored in the wrong Article
object due to the time it takes embed.ly to get the data.
This creates a problem when the getRedditLinks
function runs again for the next subreddit. The i
resets meaning the extractEmbedlyData
function only gets the embed.ly data for the links from the first subreddit. If you run the code (here is a fiddle) and look in the console you will see what I mean - there is no embedly data for the last 5 Articles
.
So the challenge is, bearing in mind that emded.ly will not pull data at the same rate as reddit does, to ensure that both sets of data are stored in the correct Article
object.
I have tried storing the article array for each subreddit in a master associative array/object using dynamic names with the little success. This may be possible but I haven't worked out how to do it.
If you know how to create dynamicly named associative arrays/objects in this kind of situation please can you it explain it to me. Alternatively, if you can think of a better solution and would like to explain it or at least point me in the right direction for research that would be greatly appreciated.
Here is the code: HTML:
<script src="http://cdn.embed.ly/jquery.embedly-3.1.1.min.js"></script>
JavaScript:
//Set embed.ly default key
$.embedly.defaults.key = 'a1206fe3b4214b3483b27db1a0a4f2e4';
//An array of subreddits which will eventually be generated from user input.
var userInput = ["nottheonion", "offbeat"]
//Iterate throught the userInputs, runnning the getRedditLinks function on each one.
for (var i = 0; i < userInput.length; i++) {
getRedditLinks(userInput[i]);
};
//Declare articles array where the Article objects will be stored
var articles = [];
//Article constructor
function Article(url, title, subreddit) {
this.url = url;
this.title = title;
this.description;
this.imgsrc;
this.rank;
this.subreddit = subreddit;
}
//Get Reddit URLs, titles and votes from a subreddit using JSON and store in new Articles. Push the Articles to the article array.
function getRedditLinks(subredditInput) {
$.getJSON(
"http://www.reddit.com/r/" + subredditInput + ".json?jsonp=?",
function foo(data) {
var ddc = data.data.children;
for (i = 0; i < 5 && i < ddc.length; i++) {
articles.push(new Article(ddc[i].data.url, ddc[i].data.title, ddc[i].data.subreddit));
//Run the embedly extract function on all the urls in the array.
extractEmbedlyData(articles[i].url, i)
}
console.log(articles);
});
//Extract embedly data and add to Articles.
function extractEmbedlyData(url, i) {
$.embedly.extract(url).progress(function (data) {
articles[i].description = data.description;
articles[i].imgsrc = data.images[0].url;
articles[i].rank = i;
});
}
}
La solution
Could just pass the actual Article
object to extractEmbedlyData
instead of index
for (i = 0; i < 5 && i < ddc.length; i++) {
var article=new Article(ddc[i].data.url, ddc[i].data.title, ddc[i].data.subreddit);
articles.push(article);
extractEmbedlyData(article)
}
function extractEmbedlyData(article) {
$.embedly.extract(article.url).progress(function (data) {
article.description = data.description;
article.imgsrc = data.images[0].url;
article.rank = i;
});
}