JavaScript AJAX Basics (retiring) Programming AJAX Stage 2 Challenge

Getting Reusable Function to Work

I'm trying to get this function to work, so I can use again. Instead of duplicating a code.

function createList(requestName, variableName, key1, key2, idName) {
  if(requestName.readyState === 4 && requestName.status === 200) {
    var variableName = JSON.parse(requestName.responseText);
    var statusHTML = '<ul class="bulleted">';
    for (var i=0; i<variableName.length; i += 1) {
      if (variableName[i].key1 === true) {
        statusHTML += '<li class="in">';
      } else {
        statusHTML += '<li class="out">';
      }
      statusHTML += variableName[i].key2;
      statusHTML += '</li>';
    }
    statusHTML += '</ul>';
    document.getElementById(idName).innerHTML = statusHTML;
  }
}

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = createList(xhr, employees, inoffice, name, 'employeeList' );
xhr.open('GET', '../data/employees.json');
xhr.send();

Can anyone help me to fix this?

Chyno Deluxe
Chyno Deluxe
16,871 Points

//Fixed Code Presentation

3 Answers

Not sure if this is what you were going for too but I wanted to have the same code work for both instances since the requests were so similar. This is what I came up with

function getRequest(type, url) {
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
      var dataObject = JSON.parse(xhr.responseText);
      // set to empty string so it wont add to undefined string
      var htmlContent = "";
      var trueClass, falseClass, objectName, objectBoolean;
      if (type === 'room') {
        trueClass = 'empty';
        falseClass = 'full';
        objectName = 'room';
        objectBoolean = 'available';
      }
      if (type === 'employee') {
        trueClass = 'in';
        falseClass = 'out';
        objectName = 'name';
        objectBoolean = 'inoffice';
      }
      for (var i=0; i<dataObject.length; i += 1) {
        if (dataObject[i][objectBoolean]) {
          htmlContent += '<li class="' + trueClass +'">';
        } else {
          htmlContent += '<li class="' + falseClass +'">';
        }
        htmlContent += dataObject[i][objectName];
        htmlContent += '</li>';
      }
      // get the ul with the name of the list instead of writing the ul in here
      document.getElementById(type + 'List').innerHTML = htmlContent;
    }
  }
  xhr.open('GET', url);
  xhr.send();
}

getRequest('room', '../data/rooms.json');
getRequest('employee', '../data/employees.json');
Calvin Miracle
Calvin Miracle
19,143 Points

Take a look at your line statusHTML += variableName[i].key2;

I know you're trying to use a parameter when the function is called, but that line looks like you're trying to call a property .key2 on variableName that already exists..

Try statusHTML += variableName[i].[key2]; to bring out the fact that key2 is a string variable containing the object property name..

I hope this helps, take care!

-- Cal

I came to a conclusion that xhr.onreadystatechange doesn't like any brackets. It only works when I create a variable and add an anonymous function to it and then simply add that variable to xhr.onreadystatechange.

Like this:

xhr.onreadystatechange = nameOfVariable;

But this wont work:

xhr.onreadystatechange = nameOfVariable();

Anyone know why?

When you insert an anonymous function within a named variable, that is called a function expression.

When you put empty brackets after a function name (whether you used a function declaration or function expression to name it), you are calling that function, and the call is immediate. When the javaScript interpreter reads nameOfVariable(), it immediate funs the function called nameOfVariable of contained within nameOfVariable. So, in the case of an event listener (onreadystatechange is an event listener), you actually aren't waiting for the event listener to run the function if you put the () after it, you are running it as soon as the browsers JSI runs over that code. Take off the parentheses, as you discovered, and the function will only be run when the event fires.

Hope this help! This topic is covered in some more detail in Andrew Chalkley's "Interactive Web Pages With JavaScript Course": https://teamtreehouse.com/library/interactive-web-pages-with-javascript