October 13, 2015 8:27 am

Creating a HTML5 app that shows gags in real-time Part 3

Our Worker located in workers/infinigag.js loads the first page of Infinigag’s API with the latest scraped gags from the category the user specified in the UI and repeats this process every 60 seconds. If on the second, third, etc. iteration the worker finds that there are new gags – it will return to our main app’s logic the number of new gags along with markup to be added to the page with the new gags.
Creating a HTML5 app that shows gags in real-time 1

[wpdm_file id=150]DEMO

The Worker will start working as soon as the user has specified a category and our main logic sends a message to the worker with the category:

var gags;

onmessage = function(evt) {
var category = evt.data,res,allImages= [], changedPictures;

if (gags) {
clearInterval(gags);
}
gags  = setInterval(loadGags, 1000 * 60 );
loadGags();

Therefore, whenever we receive a message we clear previous intervals (because we do not want to search for new gags in a category the user has specified before or set two intervals) and define an interval to call the loadGags function each minute. We also call the function immediately as we do not want to wait a minute before the first gags arrive to the user.

Afterwards, we define our loadGags function which issues a XMLHttpRequest to a specified category of the Infinigag API. If a response has arrived, we check if there are items stored in the allImages array (that array would hold the URLs of all images currently displayed to the user so that we can determine if new gags have arrived by checking if and how many of the new response’s image URLs are already in the array – if they are not in the array, then they are new).

function loadGags() {

var xhr = new XMLHttpRequest();
xhr.open("GET", "http://infinigag.eu01.aws.af.cm/" + category +  "/0");
xhr.onreadystatechange = function(evt) {
if (xhr.status === 200 && xhr.readyState === 4) {
res = JSON.parse(xhr.responseText);
if (allImages.length) {

changedPictures = 0;

for (var i = 0; i < res.data.length;i++) {
if (allImages.indexOf(res.data[i].images.normal) === -1 ) {
changedPictures+=1;

}
}
}
else {
changedPictures = res.data.length;
}

We determine how many new pictures as mentioned above and store the number of new gags in the changedPictures variable, if the array with image URLs is empty this means all gags are new  so we set the changedPictures variable to be equal to the number of gags in the response.

Then, we start iterating until there are changed (new) pictures (gags) and craft the final markup from the different parts of the returned JSON. It is important to note that new gags will be at the lowest indices (0,1,2) and so on. Thus, if there is 1 new gag it will be at res.data[0] and if there are 3 new gags, the third gag would be available at res.data[2]. This allows us to start looping from zero, increment our counter and keep adding gags until there are no new gags (as we have determined the number of new gags before and stored the result in changedPictures)

ar out = "";
for (var i = 0; i < changedPictures;i++) {
allImages.push(res.data[i].images.normal);
out += "<div class='gag col-md-6 col-md-offset-3'>";
out += "<div class='thumbnail'>";
out += "<a href='" + res.data[i].images.large + "' target='_blank'>" +
"<img class='img-responsive img-rounded' src='" + res.data[i].images.normal + "' alt='" +
res.data[i].caption + "'></a>";
out += "<div class='caption'><p>" + res.data[i].caption + "</p>" +
"<p>Votes: " + numberWithCommas(res.data[i].votes.count) + "</p>" +
"<p>To see the gag in its original place, visit: <a href='" + res.data[i].link + "' target='_blank'>" +
res.data[i].link + "</a>";
out += "<p class='likes'><a class='glyphicon glyphicon-thumbs-up' href='" + res.data[i].actions.like + "' target='_blank'>" +
"<a class='glyphicon glyphicon-thumbs-down' href='" + res.data[i].actions.dislike + "' target='_blank'> </p>"
out += "</div></div></div>";
}

Near the end, we send a message to our main logic indicating the number of new gags, only if there are new ones and send the output (the markup) we have created so that the main logic can add it to the DOM using the postMessage function which takes the message to send as a parameter:

if (changedPictures) {
    postMessage({newGags: changedPictures});
}postMessage(out);

We do all this because, as you might have guessed, Web Workers do not have access to the DOM. If you want to use your own library or a third-party library when using a Web Worker you can do that using the importScripts function.

Conclusion

We hope this article has served you as a healthy introduction as to what is possible with the Notifications API and Web Workers in HTML5.

Author Ivan Dimov

Ivan is a student of IT, a freelance web designer/developer and a tech writer. He deals with both front-end and back-end stuff. Whenever he is not in front of an Internet-enabled device he is probably reading a book or traveling. You can find more about him at: http://www.dimoff.biz. facebook, twitter


Tutorial Categories:

Leave a Reply

Your email address will not be published. Required fields are marked *