DEV Community

Cover image for Doctor Who Database
Joseph Martin
Joseph Martin

Posted on

Doctor Who Database

My phase 1 project is a visual database of Doctor Who episodes. To view my website click here. Information about episodes can be retrieved by season, Doctor, director, or writer This could be considered a companion app to the Doctor Who Series. While working on this project I had to come up with some creative solutions to a couple challenges I was facing.

Image description
The first challenge was to prevent having to scroll to see information. For example, when you first click on a category; season, Doctor, director, or writer(in the example above we are looking at seasons); it fetches the endpoint for that category, and renders all items for that category(all of the seasons for this example) to the page. Since there's over 39 seasons the list can be long. When you click on a season you see all the episodes for that season. Now, lets say you want to see the episodes for the very last season. You click on that season, and nothing happens... That's because you have to scroll all the way back up to the top to see that information. So, I wanted to make the information display on screen no matter where I was on the page. I fixed this in CSS by setting position: fixed; on the container that holds the list of episodes. Now, this made the information stay fixed in place on the screen, but it was overlapping with the list of seasons. To fix this I moved the container. The final CSS looked like:

#episodes-container {
    position: fixed;
    top: 260px;
    left: 25%;
}
Enter fullscreen mode Exit fullscreen mode

The top: 260px; made the container display 10 pixels beneath my 250 pixel header, and the left: 25%; made the container display 25% of the way across from the left side of the window.

The second challenge was more difficult to solve. The structure of the API did not easily allow episode details to be displayed. Each category has it's own endpoint within the API that I used, catalogopolis. While the endpoint had a way to see what episodes pertained to each item in the category, it did not show the episode details. To see the episode details you had to find it within the episodes endpoint. The two endpoints did not share any data except the episode name. So, I had to come up with a way to take the episode name, fetch the episodes endpoint, and find where the episode names matched. I'm going to break the code down for you. First I saved my endpoint to a variable: const allEpisodesURL = 'https://api.catalogopolis.xyz/v1/episodes' from there I ran a fetch on the endpoint:

function fetchAllEpisodes(episodeName) {
    fetch(allEpisodesURL)
    .then(r => r.json())
    .then(episodes => findEpisode(episodes, episodeName))
}
Enter fullscreen mode Exit fullscreen mode

in fetchAllEpisodes I passed in the episodeName so it would be available to pass on to findEpisode. In findEpisode,

function findEpisode(episodes, episodeName) {
    for (let episode of episodes) {
        if(episode.title === episodeName) {
            renderEpisodeDetails(episode)
            break;
        } else {
            renderNoEpisodeDetails(episodeName)
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

I am iterating through the array of episodes. I am looking at each episode and checking if the episodeName strictly equals the episode.title. If we find the matching episode we pass it to renderEpisodeDetails. If we don't find the matching episode we pass it to renderNoEpisodeDetails. In render episode details,

function renderEpisodeDetails(episode) {
    episodeDetailsContainer.innerText = ''
    let title = create('p')
    let airDate = create('p')
    let runtime = create('p')
    let viewers = create('p')
    let rating = create('p')
    title.innerText = episode.title
    airDate.innerText = `Aired: ${episode.originalAirDate.slice(5)}-${episode.originalAirDate.slice(0, 4)}`
    runtime.innerText = `Runtime: ${episode.runtime}`
    viewers.innerText = `Viewers: ${episode.ukViewersMM} million `
    rating.innerText = `Rating: ${episode.appreciationIndex} / 100`
    episodeDetailsContainer.append(title, airDate, runtime, viewers, rating)
}
Enter fullscreen mode Exit fullscreen mode

I create a p tag for each detail, fill in the innerText of each detail with data returned from the API, and append it all to the container that holds the episode details. A quick side note, create is a helper function I added to the top of my file,

const create = el => document.createElement(el)
Enter fullscreen mode Exit fullscreen mode

And now, if we back up a little, if no episode details were found in findEpisode we pass the episodeName to renderNoEpisodeDetails,

function renderNoEpisodeDetails(episodeName) {
    episodeDetailsContainer.innerText = `${episodeName} is not in the database`
}
Enter fullscreen mode Exit fullscreen mode

in renderNoEpisodeDetails I am setting the innerText of the episodeDetailsContainer to say, episodeName is not in the database.

Finding solutions to these two challenges made the project easier to navigate and provided additional information.

Top comments (0)