Brad
Brad

Reputation: 331

How to access the results of two nested .forEach in the larger function

The pen is here: https://codepen.io/BradCoffield/pen/WEWXqO

I have a getJSON and inside of it I'm processing returned data and building what should get sent to the HTML using 2 .forEach

I want to pull the results of each .forEach, concatenate them and append them to an ID. But the variables aren't accessible to the outer area of the function and I don't know what to do.

$(document).ready(function () {

$.getJSON("https://api3.libcal.com/api_hours_grid.php?iid=000&format=json&weeks=1&systemTime=0&callback=?", function (json) {

    var day0 = (json.locations[0].weeks[0].Sunday);
    var day1 = (json.locations[0].weeks[0].Monday);
    var day2 = (json.locations[0].weeks[0].Tuesday);
    var day3 = (json.locations[0].weeks[0].Wednesday);
    var day4 = (json.locations[0].weeks[0].Thursday);
    var day5 = (json.locations[0].weeks[0].Friday);
    var day6 = (json.locations[0].weeks[0].Saturday);

    var days = [day0, day1, day2, day3, day4, day5];
    var dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];


    dayNames.forEach(function (foo) {
        var someContent = "<li id='" + foo + '-hours'+"'><span class='day-of-week'>" + foo + ", "


    });

    days.forEach(function (element) {

        var dayDate = element.date
        var dayDay = element.rendered

        if (dayDate[5] === '0') {
            dayDate = dayDate.substr(6)
        } else {
            dayDate = dayDate.substr(5)
        }

        var moreContent = "" +  dayDate + ":</span> " + "<span class='dates'>" + dayDay + "</li>"

    });


    var forHTML = someContent + moreContent;


    $('#this-weeks-hours').append(forHTML);


});});

Upvotes: 0

Views: 280

Answers (3)

MR0
MR0

Reputation: 164

you can use reduce to concatenate all vars. some like this:

days.reduce(function (out, element) {

    var dayDate = element.date
    var dayDay = element.rendered

    if (dayDate[5] === '0') {
        dayDate = dayDate.substr(6)
    } else {
        dayDate = dayDate.substr(5)
    }

    return out += "" +  dayDate + ":</span> " + "<span class='dates'>" + dayDay + "</li>"

}, '');

for more info check: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce?v=b

Upvotes: 0

Carsten Massmann
Carsten Massmann

Reputation: 28196

I know this question already has an answer, but since you were not quite pleased with your own result, maybe the following is still interesting to you?

Assuming that jsn holds the response from your JSONP request, the code can be shortened to essentially the following lines:

var dates=Object.entries(jsn.locations[0].weeks[0]).map(function(val,key)
          {
             return '<li>'+key+' '+val[0]+' '+val[1].date
                    +': '+val[1].rendered+'</li>';
          })
$('#this-weeks-hours').append('<ul>'+dates.join('\n')+'</ul>');

The above code of course needs to be placed within the callback function of your getJSON() call.

See here for a working demo (without Ajax):

var jsn={"locations":[{"lid":558,
 "name":"Today's Hours:&nbsp;&nbsp;",
 "category":"library",
 "desc":"",
 "url":"http:\/\/library.francis.edu",
 "contact":"<p>For questions concerning your registration for Workshops, please email [email protected]<\/p>\r\n\r\n<p>&nbsp;<\/p>",
 "fn":"",
 "lat":"",
 "long":"",
 "color":"#980326",
 "weeks":[{"Sunday"   :{"times":{"currently_open":false,"status":"open","hours":[{"from":   "1pm","to":"11pm"}]},"date":"2017-09-03","rendered":   "1pm - 11pm"},
           "Monday"   :{"times":{"currently_open":false,"status":"open","hours":[{"from":"7:30am","to":"11pm"}]},"date":"2017-09-04","rendered":"7:30am - 11pm"},
           "Tuesday"  :{"times":{"currently_open":true, "status":"open","hours":[{"from":"7:30am","to":"11pm"}]},"date":"2017-09-05","rendered":"7:30am - 11pm"},
           "Wednesday":{"times":{"currently_open":false,"status":"open","hours":[{"from":"7:30am","to":"11pm"}]},"date":"2017-09-06","rendered":"7:30am - 11pm"},
           "Thursday" :{"times":{"currently_open":false,"status":"open","hours":[{"from":"7:30am","to":"11pm"}]},"date":"2017-09-07","rendered":"7:30am - 11pm"},
           "Friday"   :{"times":{"currently_open":false,"status":"open","hours":[{"from":"7:30am","to": "4pm"}]},"date":"2017-09-08","rendered":"7:30am - 4pm"},
           "Saturday" :{"times":{"currently_open":false,"status":"open","hours":[{"from":  "12pm","to": "5pm"}]},"date":"2017-09-09","rendered":  "12pm - 5pm"}}]
 }]};


var dates=Object.entries(jsn.locations[0].weeks[0])
          .map(function(val,key){return '<li>'+key+' '+val[0]+' '+val[1].date+': '+val[1].rendered+'</li>';})
$('#this-weeks-hours').append('<ul>'+dates.join('\n')+'</ul>');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>This week's opening hours</h2>
<div id="this-weeks-hours"></div>

No need to set up the extra arrays days or dayNames.

Upvotes: 2

i.terrible
i.terrible

Reputation: 157

Not 100% sure if that is what you aim for, but just declare & init the variables in the same scope as your rendering call. I modified your code to do that.

$(document).ready(function () {

    $.getJSON("https://api3.libcal.com/api_hours_grid.php?iid=587&format=json&weeks=1&systemTime=0&callback=?", function (json) {

        //content variables declared here
        ///////////////////////////////////////////
        var someContent = '';
        var moreContent = '';
        ///////////////////////////////////////////


        var day0 = (json.locations[0].weeks[0].Sunday);
        var day1 = (json.locations[0].weeks[0].Monday);
        var day2 = (json.locations[0].weeks[0].Tuesday);
        var day3 = (json.locations[0].weeks[0].Wednesday);
        var day4 = (json.locations[0].weeks[0].Thursday);
        var day5 = (json.locations[0].weeks[0].Friday);
        var day6 = (json.locations[0].weeks[0].Saturday);

        var days = [day0, day1, day2, day3, day4, day5];
        var dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];


        dayNames.forEach(function (foo) {
            someContent += "<li id='" + foo + '-hours'+"'><span class='day-of-week'>" + foo + ", "


        });

        days.forEach(function (element) {

            var dayDate = element.date
            var dayDay = element.rendered

            if (dayDate[5] === '0') {
                dayDate = dayDate.substr(6)
            } else {
                dayDate = dayDate.substr(5)
            }

            moreContent += "" +  dayDate + ":</span> " + "<span class='dates'>" + dayDay + "</li>"

        });


        var forHTML = someContent + moreContent;
        $('#this-weeks-hours').append(forHTML);


    });

});

Upvotes: 2

Related Questions