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! While you're at it, check out some resources Treehouse students have shared here.

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 Object-Oriented JavaScript (2015) Constructor Functions and Prototypes Making the UI Work

Items for Playlist are not showing...

From what I can tell, my code is the same as in the video, but when I run it, the individual songs are not displaying on the playlist.

My code is as follows:

// Song.js

function Song(title, artist, duration) {
  this.title = title;
  this.artist = artist;
  this.duration = duration;
  this.isPlaying = false;
}

Song.prototype.play = function() {
  this.isPlaying = true;
};

Song.prototype.stop = function() {
  this.isPlaying = false;
};  

Song.prototype.toHTML = function() {
  var htmlString = '<li';
  if (this.isPlaying) {
    var htmlString += ' class="current"';
  }
  var htmlString += '>'
  var htmlString += this.title;
  var htmlString += ' - ';
  var htmlString += this.artist;
  var htmlString += ' ';
  var htmlString += '<span class="duration">';
  var htmlString += this.duration;
  var htmlString += '</span></li>';

  return htmlString;
};
// Playlist.js

function Playlist() {
  this.songs = [];
  this.nowPlayingIndex = 0;
}

Playlist.prototype.add = function(song) {
this.songs.push(song);
};

Playlist.prototype.play = function() {
  var currentSong = this.songs[this.nowPlayingIndex];
  currentSong.play();
};

Playlist.prototype.stop = function(){
  var currentSong = this.songs[this.nowPlayingIndex];
  currentSong.stop();
};

Playlist.prototype.next = function() {
  this.stop();
  this.nowPlayingIndex++;
  if (this.nowPlayingIndex === this.songs.length) {
   this.nowPlayingIndex = 0;
  }
  this.play();
};

Playlist.prototype.renderInElement = function(list) {
  list.innerHTML = "";
  for (var i = 0; i < this.songs.length; i ++) {
    list.innerHTML = this.songs.[i].toHTML();
  }
};
// App.js

var playlist = new Playlist();

var song1 = new Song("Carnival", "The Pillows", "2.25");
var song2 = new Song("Last Dino", "The Pillows", "3.00");
var song3 = new Song("1989", "The Pillows", "5.00");

playlist.add(song1);
playlist.add(song2);
playlist.add(song3);

var playlistElement = document.getElementById("playlist");

playlist.renderInElement(playlistElement);


var playButton = getElementById("play");
playButton.onclick = function () {
  playlist.play();
  playlist.renderInElement(playlistElement);
}
var nextButton = getElementById("next");
nextButton.onclick = function () {
  playlist.next();
  playlist.renderInElement(playlistElement);
}
var stopButton = getElementById("stop");
stopButton.onclick = function () {
  playlist.stop();
  playlist.renderInElement(playlistElement);
}

Any assistance or insight would be appreciated :)

Thanks!

2 Answers

Hey William,

It looks like the problem is your Playlist.prototype.renderInElement method. Inside the for loop, you're just re-assigning list.innerHTML over and over again... each time rewriting its previous value. Probably just a typo but here's what you have:

Playlist.prototype.renderInElement = function(list) {
  list.innerHTML = "";
  for (var i = 0; i < this.songs.length; i ++) {
    list.innerHTML = this.songs.[i].toHTML(); //This is the line I'm talking about...
  }
};

And here's what you should have:

Playlist.prototype.renderInElement = function(list) {
    list.innerHTML = "";
    for(var i=0; i < this.songs.length; i++) {
        list.innerHTML += this.songs[i].toHTML(); //This is the line I'm talking about...
    }
};

Also, inside the Song.prototype.toHTML method, you used var to many times... again, probably a typo (copy-and-pasted incorrectly...) but, here's what you have:

Song.prototype.toHTML = function() {
  var htmlString = '<li';
  if (this.isPlaying) {
    var htmlString += ' class="current"';
  }
  var htmlString += '>'
  var htmlString += this.title;
  var htmlString += ' - ';
  var htmlString += this.artist;
  var htmlString += ' ';
  var htmlString += '<span class="duration">';
  var htmlString += this.duration;
  var htmlString += '</span></li>';

  return htmlString;
};

And here's a more correct version:

Song.prototype.toHTML = function() {
    var htmlString = '<li';

    if(this.isPlaying) {
        htmlString += ' class="current"';
    }
    htmlString +='>' + this.title + ' - ' + this.artist + '<span class="duration">' + this.duration + '</span></li>';
    return htmlString;
};

That should work now :)

I changed that one line in the playlist.prototype method to read:

list.innerHTML += this.songs[i].toHTML();

but I still have the same issue.

In response to Andrew Chalkley, I get three error messages in the JavaScript console. The first two have to do with the if statements in movie.js and song.js:

Uncaught SyntaxError: Unexpected token += movie.js : 11

Uncaught SyntaxError: Unexpected token += song.js : 11

// movie.js

if (this.isPlaying) {
    var htmlString += ' class="current"';
  }

// the "var htmlString..." is Line 11
// song.js

  if (this.isPlaying) {
    var htmlString += ' class="current"';
  }

// the "var htmlString..." is Line 11 here as well    

The third error message is:

Uncaught ReferenceError: Song is not defined app.js : 3

Line 3 in app.js is as follows:

var song1 = new Song("Carnival", "The Pillows", "2.25");

Thanks!

Hey William,

movie.js should look like this:

function Movie(title, year, duration) {
    Media.call(this, title, duration);
    this.year = year;
}

Movie.prototype = Object.create(Media.prototype);

Movie.prototype.toHTML = function() {
  var htmlString = '<li';
  if(this.isPlaying) {
    htmlString += ' class="current"';
  }
  htmlString += '>';
  htmlString += this.title;
  htmlString += ' (';
  htmlString += this.year;
  htmlString += ') ';
  htmlString += '<span class="duration">';
  htmlString += this.duration;
  htmlString += '</span></li>';
  return htmlString;
};

and song.js should look like this:

function Song(title, artist, duration) {
    Media.call(this, title, duration);
    this.artist = artist;
}

Song.prototype = Object.create(Media.prototype);

Song.prototype.toHTML = function() {
  var htmlString = '<li';
  if(this.isPlaying) {
    htmlString += ' class="current"';
  }
  htmlString += '>';
  htmlString += this.title;
  htmlString += ' - ';
  htmlString += this.artist;
  htmlString += '<span class="duration">';
  htmlString += this.duration;
  htmlString += '</span></li>';
  return htmlString;
};

It seems like the problem is that you're still using var too many times... try fixing that and see if it works.

Andrew Chalkley
STAFF
Andrew Chalkley
Treehouse Guest Teacher

When you open up the developer console are there any errors?

I haven't finished it yet Andrew, but so far it's a great course — very effective. Good job!