Skip to content

Maintenance: replace dead Breaking Bad API with TVmaze, fix error handling & a11y - #1

Merged
fadyehabamer merged 9 commits into
masterfrom
maintenance/2026-09
Sep 24, 2026
Merged

fadyehabamer merged 9 commits into
masterfrom
maintenance/2026-09

Conversation

@fadyehabamer

Copy link
Copy Markdown
Owner

The app is completely broken in production: breakingbadapi.com no longer exists (DNS lookup fails), so the page shows "Loading..." forever and throws an unhandled rejection. This PR moves the app to the TVmaze API and fixes several robustness and accessibility issues.

Changes

  • Data source: load the Breaking Bad cast from TVmaze (https://api.tvmaze.com/shows/169/cast), which is free, needs no key and allows CORS, then filter it locally by character or actor name.
    • TVmaze has no nickname, status or occupation fields, so each card now shows the character, the actor and the actor's birthday. This also fixes a bug where the Name and Actor labels were swapped.
    • Cards are built with textContent instead of interpolating API data into innerHTML, which removes an injection path.
  • Show an error message when loading fails instead of an endless spinner.
  • Search filters as you type (it used to run only on blur/Enter) and shows "No characters found." when nothing matches. Typing while the data is still loading no longer overwrites the loading or error message.
  • Audio: audio.play() on load is blocked by browsers without a user gesture, which caused an unhandled rejection. When autoplay was allowed, there was no way to stop the music (WCAG 1.4.2). The rejection is now caught, and a Play/Pause button with aria-pressed was added.
  • Accessibility: alt text on the logo, a visually hidden <label> for the search box, an empty alt on the decorative loader, and focusable cards that reveal their details on :focus (before, details appeared only on hover, so keyboard and touch users couldn't see them).
  • Replace the "BB API" title with a descriptive one and add a meta description.
  • Credit TVmaze with a link back, as its CC BY-SA license requires.
  • README: data source, how to run locally, and features.

Verification (static only, no browser)

  • node --check main.js passes. index.html parses with balanced tags, and every local asset it references (in HTML, JS and CSS) exists.
  • I checked the endpoints with curl. breakingbadapi.com fails with Could not resolve host. api.tvmaze.com/shows/169/cast returns 200 with 11 cast entries and access-control-allow-origin: *. The Bootstrap CDN URL returns 200.
  • I ran main.js against index.html in jsdom with the real TVmaze API and a stubbed Audio:
    • It renders 11 cards (e.g. "Walter White / Bryan Cranston / 1956-03-07").
    • Searching "cranston" gives 1 result, "zzz" shows "No characters found.", and clearing the search gives 11 again.
    • A failed fetch shows the error message.
    • Blocked autoplay leaves the button as "Play theme music". Clicking it plays the music, and clicking again pauses it.
    • There are no unhandled rejections. On master, the same harness stays on "Loading..." with unhandled fetch failed and NotAllowedError rejections.
  • There is no package.json, so there are no install, build or lint scripts to run.

For the owner to decide

  • Redeploy https://breakingbadapp.vercel.app/. The live site still serves the old code that calls the dead API.
  • Another option was the community clone breaking-bad-api-six.vercel.app, which responds and has the old fields (nickname, occupations). I chose TVmaze because it is an established, documented service. If you would rather keep the richer fields, you could switch.
  • Bootstrap 4.5.2 (loaded from StackPath) is end-of-life. Consider moving to Bootstrap 5 via jsDelivr with SRI. I didn't make that change because it could alter the layout.
  • The repo name ("BreakingBad-API") and description still refer to the old API.

breakingbadapi.com no longer resolves (DNS lookup fails), so the page was stuck on 'Loading...' forever with an unhandled fetch rejection.

Load the Breaking Bad cast (show 169) from TVmaze, which is free, keyless and CORS-enabled, and filter it locally by character or actor name. TVmaze doesn't provide nickname/status/occupation, so cards show character, actor and actor's birthday. This also fixes the Name/Actor labels, which were swapped. Cards are built with textContent instead of interpolating API data into innerHTML.
Network or HTTP errors previously left the loading spinner on screen indefinitely.
Search previously only ran on the 'change' event (blur/Enter) and a query with no matches rendered a blank area. Since filtering is now local, update on 'input' and tell the user when nothing matches.
… music

Browsers reject audio.play() without a user gesture, which produced an unhandled promise rejection and meant the music never played. When autoplay was allowed there was no way to stop it (WCAG 1.4.2 Audio Control). Catch the rejection and add a toggle button with aria-pressed state.
…ter details

The logo had no alt text and the search box relied on its placeholder only. Character details were revealed on :hover alone, so keyboard and touch users couldn't reach them; cards are now focusable and show details on :focus. The decorative loader image gets an empty alt.
The TVmaze API license (CC BY-SA) requires crediting TVmaze with a link back from the site.
…ata loads

Typing into the search box before the cast arrived (or after it failed to load) replaced the spinner/error with a misleading 'No characters found.'
Copilot AI lite review requested due to automatic review settings September 24, 2026 11:24
@vercel

vercel Bot commented Sep 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
breaking-bad-api Ready Ready Preview Sep 24, 2026 11:24am UTC

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Address the three unresolved moderate issues in audio state synchronization, live-region announcements, and card overlay positioning.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 2 Medium severity

Open (2)
What changed in this PR

Migrates the app from the unavailable Breaking Bad API to TVmaze and improves reliability, accessibility, search, and audio controls.

Changes:

  • Replaced the dead API with TVmaze cast data and local filtering.
  • Added error/no-results states and safe DOM rendering.
  • Improved audio controls, keyboard accessibility, metadata, attribution, and documentation.
File Reviewed changes Final findings
style.css Focus-based card detail display Moderate: position card overlays relative to their cards (1 vote).
README.md Updated data source, setup, and features No final comments.
main.js Fetching, filtering, rendering, error handling, and audio controls Moderate: synchronize the toggle when audio ends (2 votes); expose status messages as a live region (2 votes).
index.html Metadata, accessible controls, and TVmaze attribution No final comments.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread main.js
Comment on lines +25 to +32
musicToggle.addEventListener("click", ()=>{
if(audio.paused){
playMusic();
}else{
audio.pause();
updateMusicToggle();
}
})
Comment thread main.js
let res;
function showMessage(text){
output.innerHTML = "";
const p = document.createElement("p");
@fadyehabamer
fadyehabamer merged commit 1667bf7 into master Sep 24, 2026
3 checks passed
@fadyehabamer
fadyehabamer deleted the maintenance/2026-09 branch September 24, 2026 12:59

This branch was successfully deployed

1 active deployment
Preview — 4595e33f Deployed Sep 24, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants