Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community!

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript AJAX Basics (retiring) Programming AJAX Stage 2 Challenge Answer

Is still DRY working when we've copied that code?

What about DRY?

James MacDonald
James MacDonald
Courses Plus Student 6,268 Points

Hi Maxim,

I think you may need to provide more context (example?) with your question in order for others to help you.


Copy pasting isn't dry DRY - it's more code to maintain and subtle changes between different versions of copy-pasted code makes things hard to find.

It's a good place to start however - to first create the duplication - get things working - and then to extract the common functionality into a generalised function that you'll be able to reuse later.

For example, to build further on what Pedro Baptista has commented:

function requestList(list_id, source_url, listClass, statusField, nameField, trueClass, falseClass){
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function () {
    if(xhr.readyState === 4 && xhr.status === 200) {
      var table = JSON.parse(xhr.responseText);
      document.getElementById(list_id).innerHTML = composeList(table, listClass, statusField, nameField, trueClass, falseClass);
  xhr.open('GET', source_url);

requestList('employeeList','../data/employees.json', 'bulleted', 'inoffice', 'name', 'in', 'out')
requestList('roomList','../data/rooms.json', 'rooms', 'available', 'room', 'empty', 'full')

If you take it further - requesting JSON and parsing it is something that also gets done over and over, even that can be extracted into its own reusable function:

function getJSON(url, callback) {
    let xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
        if(xhr.readyState === XMLHttpRequest.DONE &&
               xhr.status === 200) {
    xhr.open('GET', url);

And that's how libraries like jQuery get started - by continually extracting duplication :)

7 Answers

Yes, I think so. Although the structure is exactly the same, the data sources and the values are different. For instance, the arrays are different, the class names are different, the ids are different. And, you have to create a new AJAX object for each new request.

If not, how would you get around it? If statements? I suppose...but it would be very cumbersome and maybe not very conventional if you were also working with other programmers. Plus, you'd still have to create separate AJAX objects, so it would be a lot of unnecessary work. That's my opinion anyway.

Also, it was so much more fun and easier to copy and paste!

Greg Wild
Greg Wild
15,680 Points

I'd say if you were building something with huge number of AJAX requests that are broadly similar then you'd want to look at how you could break things into composable functions. e.g., a function to handle the AJAX request, pass it into another function that checks the status, another that creates the list items, another that injects this into the right DOM node.

But it's probably overkill for this example :)

I agree with Kristin, for the sake of clarity it stays better this way, and even if we were to create a function just for creating the ul, the amount of parameters would make it rather "clunky", like this:

function composeList(table, listClass, statusField, nameField, trueClass, falseClass) {    
  var statusHTML = '<ul class="' + listClass + '">';
  for (var i=0; i<table.length; i += 1) {
    if (table[i][statusField] === true) {
      statusHTML += '<li class="' + trueClass + '">';
    } else {
      statusHTML += '<li class="' + falseClass + '">';
    statusHTML += table[i][nameField];
    statusHTML += '</li>';
  statusHTML += '</ul>';
  return statusHTML;

var employees = new XMLHttpRequest();
employees.onreadystatechange = function () {
  if(employees.readyState === 4 && employees.status === 200) {
    var table = JSON.parse(employees.responseText);            
    document.getElementById('employeeList').innerHTML = composeList(table, 'bulleted', 'inoffice', 'name', 'in', 'out');
employees.open('GET', '../data/employees.json');

var rooms = new XMLHttpRequest();
rooms.onreadystatechange = function () {
  if(rooms.readyState === 4 && rooms.status === 200) {
    var table = JSON.parse(rooms.responseText);            
    document.getElementById('roomList').innerHTML = composeList(table, 'rooms', 'available', 'room', 'empty', 'full');
rooms.open('GET', '../data/rooms.json');

In the video. When Dave copied his code. Here is link https://teamtreehouse.com/forum/video:13072

Cale Matteson
Cale Matteson
11,303 Points

Hey Maxim,

I'm going to say that yes, this is probably the best way to still use DRY programming. It's temping to think that you could probably make this all work with one function. Moreover; it would probably work. Although I would say it would only work in this context. If you wanted to create a universal function to handle any and all possible outcomes (ie. other than just a <ul> with X amount of <li>'s), I don not think it would be possible without being immensely complicated. I personally think this would be the best solution even with DRY programming in mind.

Hope that helps! Cale

Kristin Anthony
Kristin Anthony
11,099 Points

Really interesting question! It's seems like, though, in the case of AJAX that the best practice is actually to separate out the code thusly. So I think this is a situation where clarity and maintainability are given priority over not repeating oneself.

Christiaan Quyn
Christiaan Quyn
14,706 Points

Very Interesting ! First thing that popped into my mind was the DRY principle as well. Interesting comments , would love to see what a few of the treehouse teachers would have to say about this as well :D