1

Background: I am trying to pull in JSON data to populate a careers section. I've successfully requested and pulled JSON data in my first $.getJSON() request and populated the titles. The next step is pulling the posting ID URLs and opening a second request to pull the Description and Apply URL.

Problem: The second request works because I can see the objects pulled into the console but for some reason my loop does not populated the section with the description or URL. I also don't receive any console errors making it a bit difficult to pinpoint the issue. Does it have anything to do with Asynchronous request? I am a first time tinkerer with AJAX, JSON and APIs.

Some documentation on API if needed: https://dev.smartrecruiters.com/customer-api/posting-api/

// Create variable to append postings to
var postingsContainer = document.querySelector('div.job-container');

// Creates postings JSON request
$.getJSON('https://api.smartrecruiters.com/v1/companies/SynchronyGroup/postings', function(postings) {

    // Check to see if data is being pulled
    console.log(postings);

    showJobs(postings);

});

// Function that pulls json data and populates careers section
function showJobs(jsonObj) {

    // Variable that holds job postings json data
    var jobs = jsonObj['content']

    // Loop to create open position elements
    for (var i = 0; i < jobs.length; i++) {

        // Creates Column for job postings
        var jobPosting = document.createElement('div')
        jobPosting.setAttribute('class', 'col-12 col-md-6 col-lg-4 my-5 job-posting');

        // Creates Job Title 
        var jobH5 = document.createElement('h5');
        jobH5.textContent = jobs[i].name;

        jobPosting.appendChild(jobH5);
        postingsContainer.appendChild(jobPosting);

        // Store job post IDs in var
        var jobId = jobs[i].ref;

        // Creates post 2nd ID JSON request
        $.getJSON(jobId, function(data) {

            // Check to see if data is being pulled
            console.log(data);

            showDetails(data);

        });

    }
}

//Function for posting description and apply url
function showDetails(data) {

    // Loop to pull company description and apply url, then append to job posting element
    for (var j = 0; j < data.length; j++) {

        console.log("I work");

        // Creates Company Desc. and Apply Link
        var jobDetail = document.createElement('p');
        var jobApply = document.createElement('a');

        jobDetail.textContent = data[j].sections.companyDescription;
        jobApply.setAttribute('href', data[j].applyUrl);
        jobApply.setAttribute('class', 'btn-primary');

        jobPosting.appendChild(jobDetail);
        jobPosting.appendChild(jobApply);

    }
}
halfer
  • 19,824
  • 17
  • 99
  • 186
WeebleWobb
  • 179
  • 14

2 Answers2

1

Your main issue is the value of jobPosting var.

This variable is created in showJobs function at each loop iteration, but you never pass this variable to the showDetails function.

Because this variable is created at each iteration you need to assure to pass the correct value (for more info you may take a look to js closure and how it works). In your case, because the $.getJSON(jobId, function(data) { you cannot simply use the variable name. If so, you will pass the last value: the value you have at the end of loop. This means you need to close the context.

In order to achive this you may use IIFE. For more info about this you can refer to this question: What is the (function() { } )() construct in JavaScript?.

The example:

// Create variable to append postings to
var postingsContainer = document.querySelector('div.job-container');

// Creates postings JSON request
$.getJSON('https://api.smartrecruiters.com/v1/companies/SynchronyGroup/postings', function (postings) {

    // Check to see if data is being pulled
    //console.log(postings);

    showJobs(postings);

});

// Function that pulls json data and populates careers section
function showJobs(jsonObj) {

    // Variable that holds job postings json data
    var jobs = jsonObj['content']

    // Loop to create open position elements
    for (var i = 0; i < jobs.length; i++) {

        // Creates Column for job postings
        var jobPosting = document.createElement('div');
        jobPosting.setAttribute('class', 'col-12 col-md-6 col-lg-4 my-5 job-posting');

        // Creates Job Title
        var jobH5 = document.createElement('h5');
        jobH5.textContent = jobs[i].name;

        jobPosting.appendChild(jobH5);
        postingsContainer.appendChild(jobPosting);

        // Store job post IDs in var
        var jobId = jobs[i].ref;

        //
        //
        // IIFE
        (function (jobPosting) {
            // Creates post 2nd ID JSON request
            $.getJSON(jobId, function (data) {

                // Check to see if data is being pulled
                //console.log(data);

                showDetails(data, jobPosting);

            })
        }(jobPosting));

    }
}
//Function for posting description and apply url
function showDetails(data, jobPosting) {

    // Loop to pull company description and apply url, then append to job posting element
    //for (var j = 0; j < data.length; j++) {

    //console.log("I work");

    // Creates Company Desc. and Apply Link
    var jobDetail = document.createElement('p');
    var jobApply = document.createElement('a');

    jobDetail.textContent = 'showDetails: ' + data.company.name;
    jobApply.setAttribute('href', data.applyUrl);
    jobApply.setAttribute('class', 'btn-primary');

    jobPosting.appendChild(jobDetail);
    jobPosting.appendChild(jobApply);

    //}
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>



<div class="job-container"></div>
gaetanoM
  • 41,594
  • 6
  • 42
  • 61
  • I see that you commented the second loop, is this because a for() is not needed when using IIFE? – WeebleWobb Jul 11 '17 at 14:21
  • @WeebleWobb No, sorry, I commented the loop in the second (inner) getJson because the variable is a plain object and you cannot cycle as if was an array. You can use a different loop strategy on an object like **for(key in data)** or something similar. Thanks – gaetanoM Jul 11 '17 at 14:24
  • Ok, thank you for sharing the additional IIFE thread. A lil bit to grasp but it looks to be working. Going to have to be something I continue to tinker with to get more comfortable with but a step in the right direction. – WeebleWobb Jul 11 '17 at 14:33
  • @WeebleWobb I'm glad for you. Thanks so much – gaetanoM Jul 11 '17 at 14:34
0

Checkout this working code just need to change this line var jobs = jsonObj['content']. change the line to var jobs = jsonObj.content;

// Create variable to append postings to
var postingsContainer = document.querySelector('div.job-container');

// Creates postings JSON request
$.getJSON('https://api.smartrecruiters.com/v1/companies/SynchronyGroup/postings', function(postings) {

    // Check to see if data is being pulled
    //console.log(postings);

    showJobs(postings);

});

// Function that pulls json data and populates careers section
function showJobs(jsonObj) {

    // Variable that holds job postings json data
    var jobs = jsonObj.content;

    // Loop to create open position elements
    for (var i = 0; i < jobs.length; i++) {

        // Creates Column for job postings
        var jobPosting = document.createElement('div')
        jobPosting.setAttribute('class', 'col-12 col-md-6 col-lg-4 my-5 job-posting');

        // Creates Job Title 
        var jobH5 = document.createElement('h5');
        jobH5.textContent = jobs[i].name;

        jobPosting.appendChild(jobH5);
        postingsContainer.appendChild(jobPosting);

        // Store job post IDs in var
        var jobId = jobs[i].ref;

        // Creates post 2nd ID JSON request
        $.getJSON(jobId, function(data) {

            // Check to see if data is being pulled
            //console.log(data);

            showDetails(data);

        });

    }
}

//Function for posting description and apply url
function showDetails(data) {

    // Loop to pull company description and apply url, then append to job posting element
    for (var j = 0; j < data.length; j++) {

        console.log("I work");

        // Creates Company Desc. and Apply Link
        var jobDetail = document.createElement('p');
        var jobApply = document.createElement('a');

        jobDetail.textContent = data[j].sections.companyDescription;
        jobApply.setAttribute('href', data[j].applyUrl);
        jobApply.setAttribute('class', 'btn-primary');

        jobPosting.appendChild(jobDetail);
        jobPosting.appendChild(jobApply);

    }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="job-container"></div>
Pankaj Makwana
  • 3,030
  • 6
  • 31
  • 47