Chris
Chris

Reputation: 993

My closure gone wrong

Not only am I getting InnerNewsAPI() is undefined, but the closure isn't working in this code. I thought I understood closure correctly from reading You-dont-know-JS but I guess I am still really confused. What is the problem with this code, and why does my attempt of closure not work here? (Also I dont think my API link isn't working but that doesn't have anything to do with me getting "undefined" from closure right?

function NewsAPI() {
    var authorOfArticle = [],
        descriptionOfArticle = [],
        publishedAtDate = [],
        titleOfArticle = [],
        urlOfArticle = [],
        urlToImageOfArticle = [];
    var newsConstructor = new XMLHttpRequest(),
        url = 'https://newsapi.org/v1/articles?source=google-news&sortBy=top&apiKey=c99bdac4799a421cbe9fd3589b60397d';
    newsConstructor.onreadystatechange = function () {
        if (newsConstructor.readyState === 4 && newsConstructor.status === 200) {
            var response = newsConstructor.responseText,
                parsedNews = JSON.parse(response);
            for (var i = 0; i < parsedNews["articles"].length; i++) {
                authorOfArticle.push(parsedNews["articles"][i].author); // [0] = author
                descriptionOfArticle.push(parsedNews["articles"][i].description); // [1] = description of article
                publishedAtDate.push(parsedNews["articles"][i].publishedAt); // [2] = date published
                titleOfArticle.push(parsedNews["articles"][i].title); // [3] = title
                urlOfArticle.push(parsedNews["articles"][i].url); // [4] link to source
                urlToImageOfArticle.push(parsedNews["articles"][i].urlToImage); // [5] = image url
            }
            console.log(titleOfArticle);

            function InnerNewsAPI() {
                $("document").ready(function () {
                    $("#a1title").text(titleOfArticle[0]).addClass("article articletitles");
                    $("#a1author").text("Author: " + authorOfArticle[0]).addClass("articleauthors");
                    $("#a1source").attr("href", urlOfArticle[0]).text(urlOfArticle[0]).addClass("articles articlesources");
                    $("#a1image").attr("src", urlToImageOfArticle[0]).addClass("article articleimages");
                    $("#a1description").text(descriptionOfArticle[0]).addClass("articledescriptions");
                }); // put code above this line
                newsConstructor.open("GET", url, true);
                newsConstructor.send(null);
            }
        };
    }
    return InnerNewsAPI();
}
NewsAPI();

Upvotes: 0

Views: 51

Answers (1)

basil
basil

Reputation: 3612

There is no closure because your function definition and it's call placed in different scope. Also logic in your code looks wrong. You call return InnerNewsAPI() before newsConstructor.onreadystatechange handler fired. Maybe something like this is what you expect:

function NewsAPI() {
    var authorOfArticle = [], descriptionOfArticle = [], publishedAtDate = [], titleOfArticle = [], urlOfArticle = [], urlToImageOfArticle = [];
    var newsConstructor = new XMLHttpRequest(),
        url = 'https://newsapi.org/v1/articles?source=google-news&sortBy=top&apiKey=c99bdac4799a421cbe9fd3589b60397d';
        var InnerNewsAPI;
        newsConstructor.onreadystatechange = function () {
        if (newsConstructor.readyState === 4 && newsConstructor.status === 200) {
            var response = newsConstructor.responseText,
            parsedNews = JSON.parse(response);
            for (var i=0; i < parsedNews["articles"].length; i++) {
                authorOfArticle.push(parsedNews["articles"][i].author);   // [0] = author
                descriptionOfArticle.push(parsedNews["articles"][i].description);   // [1] = description of article
                publishedAtDate.push(parsedNews["articles"][i].publishedAt);   // [2] = date published
                titleOfArticle.push(parsedNews["articles"][i].title);   // [3] = title
                urlOfArticle.push(parsedNews["articles"][i].url);   // [4] link to source
                urlToImageOfArticle.push(parsedNews["articles"][i].urlToImage);   // [5] = image url
            }
            console.log(titleOfArticle);
            InnerNewsAPI = function () {
            $("document").ready(function() {
                $("#a1title").text(titleOfArticle[0]).addClass("article articletitles");
                $("#a1author").text("Author: " + authorOfArticle[0]).addClass("articleauthors");
                $("#a1source").attr("href",urlOfArticle[0]).text(urlOfArticle[0]).addClass("articles articlesources");
                $("#a1image").attr("src", urlToImageOfArticle[0]).addClass("article articleimages"); 
                $("#a1description").text(descriptionOfArticle[0]).addClass("articledescriptions");
        });  // put code above this line
    newsConstructor.open("GET", url, true);
    newsConstructor.send(null);
        }};
        }
        return InnerNewsAPI;
}
NewsAPI();

Upvotes: 1

Related Questions