---
id: 655b4c8f636d9675953a0388
title: Step 98
challengeType: 0
dashedName: step-98
---
# --description--
If there is no next song in the playlist, use the `else` block to reset the `currentSong` key of `userData` to `null`, and its `songCurrentTime` property to `0`.
# --hints--
You should not modify the existing `if` statement and its content.
```js
assert.match(code, /if\s*\(\s*nextSongExists\s*\)\s*\{\s*playNextSong\(\s*\)\s*;?\s*.*\s*.*\s*.*\s*\}\s*;?/)
```
Your `if` statement should have an `else` block.
```js
assert.match(code, /if\s*\(\s*nextSongExists\s*\)\s*\{\s*playNextSong\(\s*\)\s*;?\s*\}\s*else\s*\{\s*.*\s*.*\s*\}\s*;?/)
```
You should use dot notation to set the `currentSong` property of `userData` to `null` in the `else` block of your `if` statement.
```js
assert.match(code, /if\s*\(\s*nextSongExists\s*\)\s*\{\s*playNextSong\(\s*\)\s*;?\s*\}\s*else\s*\{\s*userData\.currentSong\s*=\s*null\s*;?\s*.*\s*\}\s*;?/)
```
You should use dot notation to set the `songCurrentTime` property of `userData` to `0` in the `else` block of your `if`statement.
```js
assert.match(code, /if\s*\(\s*nextSongExists\s*\)\s*\{\s*playNextSong\(\s*\)\s*;?\s*\}\s*else\s*\{\s*userData\.currentSong\s*=\s*null\s*;?\s*userData\.songCurrentTime\s*=\s*0\s*;?\s*\}\s*;?/)
```
# --seed--
## --seed-contents--
```html
Learn Basic String and Array Methods by Building a Music Player App
```
```css
:root {
/* colors */
--primary-color: #dfdfe2;
--secondary-color: #ffffff;
--app-background-color: #4d4d62;
--background-color: #1b1b32;
--foreground-color: #3b3b4f;
--highlight-color: #f1be32;
/* font sizes */
--root-font-size: 16px;
font-size: var(--root-font-size);
/* font-families */
--font-headline: "Roboto Mono", monospace;
--font-family: "Lato", sans-serif;
}
*,
*::after,
*::before {
box-sizing: border-box;
}
body {
background-color: var(--app-background-color);
color: var(--primary-color);
font-family: var(--font-family);
}
h1 {
font-size: 1.125rem;
line-height: 1.6;
}
h2 {
font-size: var(--root-font-size);
}
ul {
margin: 0;
}
.container {
margin-top: 10px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
row-gap: 5px;
}
.player,
.playlist {
width: 450px;
background-color: var(--background-color);
border: 3px solid var(--foreground-color);
}
.player {
height: 260px;
padding: 10px;
display: flex;
flex-direction: column;
align-items: center;
row-gap: 10px;
}
.player-bar,
.playlist-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 5px;
width: 100%;
height: 30px;
background-color: var(--foreground-color);
}
.parallel-lines {
display: flex;
flex-wrap: wrap;
row-gap: 6px;
padding: 0 5px;
}
.parallel-lines > div {
height: 2px;
width: 100%;
min-width: 75px;
background-color: var(--highlight-color);
}
.fcc-title,
.playlist-title {
color: var(--secondary-color);
margin: 0 10px;
font-family: var(--font-headline);
}
.player-content {
display: flex;
background-color: var(--foreground-color);
width: 430px;
height: 200px;
column-gap: 13px;
align-items: center;
justify-content: center;
}
#player-album-art {
background-color: var(--secondary-color);
border: 6px solid var(--background-color);
}
#player-album-art img {
width: 150px;
display: block;
}
.player-display {
display: flex;
flex-direction: column;
row-gap: 20px;
padding: 14px;
background-color: var(--background-color);
height: 153px;
width: 226px;
}
.player-display-song-artist {
height: 80px;
}
.player-buttons svg {
fill: var(--primary-color);
}
.playing > svg {
fill: var(--highlight-color);
}
.player-buttons {
display: flex;
justify-content: space-around;
}
button {
background: transparent;
border: none;
color: var(--primary-color);
cursor: pointer;
font-size: var(--root-font-size);
outline-color: var(--highlight-color);
text-align: center;
}
.playlist-song {
outline-color: var(--highlight-color);
}
.playlist li:not(:last-child) {
border-bottom: 1px solid var(--background-color);
}
button:focus,
.playlist-song:focus {
outline-style: dashed;
outline-width: 2px;
}
/* Playlist */
.playlist {
height: auto;
padding: 10px;
display: flex;
flex-direction: column;
align-items: center;
row-gap: 10px;
}
#playlist-songs {
width: 430px;
height: 100%;
background-color: var(--foreground-color);
display: flex;
flex-direction: column;
row-gap: 8px;
padding: 8px 9px;
visibility: visible;
justify-content: start;
list-style: none;
}
.playlist-song {
display: flex;
height: 55px;
justify-content: space-between;
align-items: center;
padding: 5px;
}
[aria-current="true"] {
background-color: var(--background-color);
}
[aria-current="true"] p {
color: var(--highlight-color);
}
.playlist-song-info {
height: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
column-gap: 7px;
padding: 5px 0;
font-family: var(--font-family);
}
#player-song-title,
#player-song-artist {
margin: 0;
}
#player-song-artist {
color: var(--highlight-color);
font-size: 0.75rem;
}
#player-song-title {
font-size: 1.125rem;
}
.playlist-song-title {
font-size: 0.85rem;
width: 241px;
text-align: left;
}
.playlist-song-artist {
font-size: 0.725rem;
width: 80px;
}
.playlist-song-duration {
font-size: 0.725rem;
margin: auto;
font-family: var(--font-headline);
width: 30px;
}
.playlist-song-delete {
padding: 0;
width: 20px;
height: 20px;
}
.playlist-song-delete,
.playlist-song-delete {
fill: var(--foreground-color);
}
.playlist-song-delete:hover circle,
.playlist-song-delete:focus circle {
fill: #ff0000;
}
@media (max-width: 700px) {
.player,
.playlist {
width: 300px;
}
.player {
height: 340px;
}
#playlist-songs {
height: 280px;
padding: 5px 6px;
overflow-y: scroll;
overflow-x: hidden;
scrollbar-color: var(--background-color) var(--secondary-color);
scrollbar-width: thin;
}
#playlist-songs::-webkit-scrollbar {
width: 5px;
}
#playlist-songs::-webkit-scrollbar-track {
background: var(--background-color);
}
#playlist-songs::-webkit-scrollbar-thumb {
background: var(--secondary-color);
}
h1 {
font-size: 0.813rem;
}
h2 {
font-size: 0.75rem;
}
.player-bar,
.playlist-bar,
.player-content,
#playlist-songs {
width: 280px;
}
.playlist-song {
justify-content: space-between;
}
.playlist-song-title {
width: 140px;
}
.playlist-song-artist {
width: 40px;
}
.playlist-song-duration > button {
padding: 0;
}
.player-content {
display: inline;
position: relative;
justify-items: center;
height: 100%;
}
#player-album-art {
z-index: -100;
height: 280px;
box-shadow: none;
background: #000;
}
#player-album-art img {
width: 100%;
opacity: 0.6;
}
.player-display-song-artist {
padding: 0 10px;
}
.player-display-song-artist > p {
white-space: pre-wrap;
}
.player-display {
position: absolute;
width: 100%;
z-index: 1000;
background-color: transparent;
top: 0;
height: 280px;
justify-content: space-between;
text-align: center;
}
}
```
```js
const playlistSongs = document.getElementById("playlist-songs");
const playButton = document.getElementById("play");
const pauseButton = document.getElementById("pause");
const nextButton = document.getElementById("next");
const previousButton = document.getElementById("previous");
const shuffleButton = document.getElementById("shuffle");
const allSongs = [
{
id: 0,
title: "Hello World",
artist: "Rafael",
duration: "0:23",
src: "https://cdn.freecodecamp.org/curriculum/js-music-player/hello-world.mp3",
},
{
id: 1,
title: "In the Zone",
artist: "Rafael",
duration: "0:11",
src: "https://cdn.freecodecamp.org/curriculum/js-music-player/in-the-zone.mp3",
},
{
id: 2,
title: "Camper Cat",
artist: "Rafael",
duration: "0:21",
src: "https://cdn.freecodecamp.org/curriculum/js-music-player/camper-cat.mp3",
},
{
id: 3,
title: "Electronic",
artist: "Rafael",
duration: "0:15",
src: "https://cdn.freecodecamp.org/curriculum/js-music-player/electronic.mp3",
},
{
id: 4,
title: "Sailing Away",
artist: "Rafael",
duration: "0:22",
src: "https://cdn.freecodecamp.org/curriculum/js-music-player/sailing-away.mp3",
},
];
const audio = new Audio();
let userData = {
songs: [...allSongs],
currentSong: null,
songCurrentTime: 0,
};
const playSong = (id) => {
const song = userData?.songs.find((song) => song.id === id);
audio.src = song.src;
audio.title = song.title;
if (userData?.currentSong === null || userData?.currentSong.id !== song.id) {
audio.currentTime = 0;
} else {
audio.currentTime = userData?.songCurrentTime;
}
userData.currentSong = song;
playButton.classList.add("playing");
highlightCurrentSong();
setPlayerDisplay();
setPlayButtonAccessibleText();
audio.play();
};
const pauseSong = () => {
userData.songCurrentTime = audio.currentTime;
playButton.classList.remove("playing");
audio.pause();
};
const playNextSong = () => {
if (userData?.currentSong === null) {
playSong(userData?.songs[0].id);
} else {
const currentSongIndex = getCurrentSongIndex();
const nextSong = userData?.songs[currentSongIndex + 1];
playSong(nextSong.id);
}
};
const playPreviousSong = () => {
if (userData?.currentSong === null) return;
else {
const currentSongIndex = getCurrentSongIndex();
const previousSong = userData?.songs[currentSongIndex - 1];
playSong(previousSong.id);
}
};
const shuffle = () => {
userData?.songs.sort(() => Math.random() - 0.5);
userData.currentSong = null;
userData.songCurrentTime = 0;
renderSongs(userData?.songs);
pauseSong();
setPlayerDisplay();
setPlayButtonAccessibleText();
};
const deleteSong = (id) => {
if (userData?.currentSong?.id === id) {
userData.currentSong = null;
userData.songCurrentTime = 0;
pauseSong();
setPlayerDisplay();
}
userData.songs = userData?.songs.filter((song) => song.id !== id);
renderSongs(userData?.songs);
highlightCurrentSong();
setPlayButtonAccessibleText();
if (userData?.songs.length === 0) {
const resetButton = document.createElement("button");
const resetText = document.createTextNode("Reset Playlist");
resetButton.id = "reset";
resetButton.ariaLabel = "Reset playlist";
resetButton.appendChild(resetText);
playlistSongs.appendChild(resetButton);
resetButton.addEventListener("click", () => {
userData.songs = [...allSongs];
renderSongs(sortSongs());
setPlayButtonAccessibleText();
resetButton.remove();
});
}
};
const setPlayerDisplay = () => {
const playingSong = document.getElementById("player-song-title");
const songArtist = document.getElementById("player-song-artist");
const currentTitle = userData?.currentSong?.title;
const currentArtist = userData?.currentSong?.artist;
playingSong.textContent = currentTitle ? currentTitle : "";
songArtist.textContent = currentArtist ? currentArtist : "";
};
const highlightCurrentSong = () => {
const playlistSongElements = document.querySelectorAll(".playlist-song");
const songToHighlight = document.getElementById(
`song-${userData?.currentSong?.id}`
);
playlistSongElements.forEach((songEl) => {
songEl.removeAttribute("aria-current");
});
if (songToHighlight) songToHighlight.setAttribute("aria-current", "true");
};
const renderSongs = (array) => {
const songsHTML = array
.map((song)=> {
return `
${song.title}
${song.artist}
${song.duration}
`;
})
.join("");
playlistSongs.innerHTML = songsHTML;
};
const setPlayButtonAccessibleText = () => {
const song = userData?.currentSong || userData?.songs[0];
playButton.setAttribute(
"aria-label",
song?.title ? `Play ${song.title}` : "Play"
);
};
const getCurrentSongIndex = () => userData?.songs.indexOf(userData?.currentSong);
playButton.addEventListener("click", () => {
if (userData?.currentSong === null) {
playSong(userData?.songs[0].id);
} else {
playSong(userData?.currentSong.id);
}
});
pauseButton.addEventListener("click", pauseSong);
nextButton.addEventListener("click", playNextSong);
previousButton.addEventListener("click", playPreviousSong);
shuffleButton.addEventListener("click", shuffle);
audio.addEventListener("ended", () => {
const currentSongIndex = getCurrentSongIndex();
const nextSongExists = userData?.songs[currentSongIndex + 1] !== undefined;
--fcc-editable-region--
if (nextSongExists) {
playNextSong();
}
--fcc-editable-region--
});
const sortSongs = () => {
userData?.songs.sort((a,b) => {
if (a.title < b.title) {
return -1;
}
if (a.title > b.title) {
return 1;
}
return 0;
});
return userData?.songs;
};
renderSongs(sortSongs());
setPlayButtonAccessibleText();
```