Front-End application Troubleshooting
Learning Outcome Guide
Section titled “Learning Outcome Guide”At the end of this class, you should be able to…
- Identify and troubleshoot common front-end issues, including JavaScript errors, broken layouts, and slow performance.
- Use browser developer tools to inspect the DOM, console errors, and network activity.
- Debug JavaScript using breakpoints and step-through execution.
- Analyze network requests to identify issues with API calls.
Coding Demo
Section titled “Coding Demo”In-Class Demo Jan 2026 term
To run the coding demo, you need to have your Student Workbook open in Visual Studio Code.
-
Open the terminal window and paste in the following.
Run from the root of your repository pnpm dlx tiged --disable-cache --force DG-InClass/SDEV-1150-A04-Jan-2026/sk/lesson-25 ./src/lesson-25 -
Walk through the steps in the
ReadMe.mdof the new lesson.
Objectives
Section titled “Objectives”- Identify and diagnose common issues in web components using DevTools and automated tests
- Apply debugging techniques including inspecting Shadow DOM, analyzing events, and verifying component state
- Write targeted tests that reveal broken behaviour in components
- Fix failing behaviour by correcting attribute handling, slot rendering, and event detail propagation
Intentional Bugs & Debugging Walkthrough
Section titled “Intentional Bugs & Debugging Walkthrough”The example user-card component and main.js script include a few intentional bugs for you to discover and fix. These are designed so that your tests (and DevTools) will help you identify what is wrong.
Bug 1: Avatar attribute does not update the image
Section titled “Bug 1: Avatar attribute does not update the image”Symptom:Setting the avatar attribute on <user-card> does not change the image src, even though observedAttributes includes avatar.
avatar attribute on <user-card> does not change the image src, even though observedAttributes includes avatar.Cause:
attributeChangedCallback checks for the wrong attribute name.
static get observedAttributes() { return ['avatar'];}
attributeChangedCallback(name, oldValue, newValue) { // Bug: name check does not match the observed attribute if (name === 'avatars' && this.shadowRoot) { const img = this.shadowRoot.querySelector('img'); if (img) { img.src = newValue; } }}Fix:
Update the condition to check for 'avatar' so it matches the observed attribute.
attributeChangedCallback(name, oldValue, newValue) { if (name === 'avatar' && this.shadowRoot) { const img = this.shadowRoot.querySelector('img'); if (img) { img.src = newValue; } }}Writing a test that sets element.setAttribute('avatar', 'some-url.png') and then asserts on the img.src will expose this bug immediately.
Bug 2: Description does not render from the user property
Section titled “Bug 2: Description does not render from the user property”Symptom:When setting the <code>user</code> property (e.g., <code>card.user = { id: 'u1', name: 'Zelda', description: 'Princess of Hyrule' }</code>), the name appears correctly, but the description does not show up in the card.
<code>user</code> property (e.g., <code>card.user = { id: 'u1', name: 'Zelda', description: 'Princess of Hyrule' }</code>), the name appears correctly, but the description does not show up in the card.Cause: The selector for the description slot is slightly wrong.
_renderFromUser() { if (this.#user) { // ... avatar and name logic ... const descSlot = this.shadowRoot.querySelector('[name="descriptions"]'); if (descSlot) { descSlot.textContent = this.#user.description || ''; } }}Fix:
- Correct the selector so it matches the
slotname in the template (name="description").
const descSlot = this.shadowRoot.querySelector('[name="description"]');if (descSlot) { descSlot.textContent = this.#user.description || '';}A test that sets the user property and then asserts that the rendered description text matches the expected value will fail until this bug is fixed.
Bug 3: Follow counter does not update correctly in main.js
Section titled “Bug 3: Follow counter does not update correctly in main.js”Symptom:Clicking the Follow button on a card toggles its visual state, but the #follow-counter text does not change as expected.
#follow-counter text does not change as expected.Cause:
The event listener in main.js is reading the wrong property from the custom event detail object.
main.addEventListener('follow-change', (e) => { // Bug: uses e.detail.isFollowed, but the event detail uses "followed" followedCount += e.detail.isFollowed ? 1 : -1; const counterEl = document.querySelector('#follow-counter'); counterEl.textContent = `Followed: ${followedCount}`; console.log('follow-change:', e.detail);});The component dispatches the event like this:
this.dispatchEvent(new CustomEvent('follow-change', { detail: { id: this.getAttribute('user-id') || null, followed: this.followed }, bubbles: true, composed: true,}));Fix:
Update the listener to use the correct property name (followed).
main.addEventListener('follow-change', (e) => { followedCount += e.detail.followed ? 1 : -1; const counterEl = document.querySelector('#follow-counter'); counterEl.textContent = `Followed: ${followedCount}`; console.log('follow-change:', e.detail);});You can also write a test for the follow-change event (or manually trigger it in DevTools) to confirm that the detail payload matches what your listener expects.
These intentional bugs are meant to be discovered via failing tests and by inspecting the DOM and events in DevTools:
- Write tests first for the expected behaviour.
- Run the tests and observe which assertions fail.
- Use the failures to guide you to the corresponding bug in the component or script.
Student Exercise
Section titled “Student Exercise”NOTE: if you’ve already completed the following from the previous lesson, use those tests to help diagnose and fix the errors described above.
- Add a test for the
avatarattribute, specifically, that setting this attribute will udpate the img src attribute. - Add a test for the
userproperty, specifically, that setting this attribute will update the expected slots and image elements.
Push changes
Section titled “Push changes”git add .- Commit the changes:
git commit -m 'Lesson 25 Example'- Push your changes to the remote workbook repository:
git push origin main