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

David Avila
seal-mask
.a{fill-rule:evenodd;}techdegree
David Avila
Full Stack JavaScript Techdegree Student 5,410 Points

Problems displaying playlist

I have followed the steps in the video a few times and still can't get the playlist to display. In the console I get the following error:

Uncaught TypeError: this.songs[i].toHTML is not a function at Playlist.renderInElement (playlist.js:49)

In a different post it is suggested that the toHTML method be called without the parenthesis. However this only causes the player to display 'undefined' where the palylist should be.

Any feedback will be much appreciated.

Here is my code:

playlist.js

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

// METHODS
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) { // the list parameter refers to the <ol> selected in app.js to render the playlist
    list.innerHTML = '';
    for (var i = 0; i < this.songs.length; i++) {
        list.innerHTML += this.songs[i].toHTML;
    }
};

song.js

// CONSTRUCTOR FUNCTION        
function Song(title, artist, duration) {
    this.title = title;
    this.artist = artist;
    this.duration = duration;
    this.isPlaying = false; // sensible default for all songs that are created
}

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

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

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;
};

app.js

// CREATING A NEW PLAYLIST
var playlist = new Playlist();

// CREATING NEW SONGS
var hereComesTheSun = new Song('Here Comes the Sun', 'The Beatles', '2:54');
var walkingOnSunshine = new Song('Walking on Sunshine', 'Katrina and the Waves', '3:43');

// ADDING THE SONGS TO THE PLAYLIST
playlist.add('hereComesTheSun');
playlist.add('walkingOnSunshine');

// RENDERING THE PLAYLIST ELEMENT <ol>
var playlistElement = document.getElementById('playlist');
playlist.renderInElement(playlistElement);

Thank you!

Paolo Scamardella
Paolo Scamardella
24,828 Points

I have no way of testing this, and it would be nice to have a way to view the actual result like js fiddle or something, but I'm taking a wild guess here, and I think toHTML is a method and not a property. I believe you are missing () to invoke the method like toHTML().

1 Answer

Neil McPartlin
Neil McPartlin
14,662 Points

Hi David, Just 2 issues here.

1 - app.js, you've accidentally added the 2 songs as strings i.e. just the song name, rather than the intended name, band, duration object, so just remove the apostrophes i.e.

playlist.add(hereComesTheSun);
playlist.add(walkingOnSunshine);

2 - As you said, in playlist.js you do need the () present, so pop those back in.

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