Guest Mode:

BCA Student Stories & UpdatesLive

You
Your StorySign in & share
Er. Manoj Kumar
D5
Er. ManojActive nowPages
Day 39Advanced JavaScript & Browser APIs3 Hours Practical
Push to GitHub to Complete

Building a Dynamic GitHub Profile Explorer SPA (Async REST API Mini App)

In this hands-on project, you will build an interactive Single Page Application that connects to the live GitHub REST API. Students enter any GitHub developer username to fetch real profile data, avatar images, follower statistics, and their latest public open-source repositories.

Interactive Learning Roadmap

Day 39 Step-by-Step Practical Flow

🎯1. What You Will Learn Today

✔Consume the real-world GitHub Public REST API (https://api.github.com/users/{username}).
✔Display avatar, bio, follower count, and public repository counts in a styled developer card.
✔Fetch and display a secondary sub-resource: top 5 repositories sorted by stars.
✔Handle 404 User Not Found gracefully with an attractive error illustration.
✔Implement an input debounce or form submit handler to avoid exceeding GitHub API rate limits.
Day 39 MasterclassAdvanced JavaScript & Browser APIs

Building a Dynamic GitHub Profile Explorer SPA (Async REST API Mini App) — Comprehensive Practical Guide

Har concept ko visual mental models, code anatomy aur practical industry tips ke sath samjhein.

Real-World Purpose Aur Zaroorat

In this hands-on project, you will build an interactive Single Page Application that connects to the live GitHub REST API. Students enter any GitHub developer username to fetch real profile data, avatar images, follower statistics, and their latest public open-source repositories.

Endpoint Architecture: Primary endpoint is https://api.github.com/users/{username}; repo endpoint is /users/{username}/repos?sort=updated.
Parallel Fetching: Use Promise.all() to fetch both user details and repository lists concurrently.
404 Handling: If the user does not exist, GitHub returns status: 404. Handle this with a clear "User Not Found" state.
Rate Limiting: GitHub allows 60 unauthenticated requests per hour per IP. Handle HTTP 403 rate limit responses cleanly.
DOM Formatting: Format dates into readable strings using new Date(created_at).toLocaleDateString().
Dimaag Mein Bithane Ka Model

"Think of this application like an interactive digital identity card scanner: you provide a student enrollment ID (username), and the terminal instantly queries the central university registry to pull up their complete academic portfolio."

💡 Pro Tip: Code ko ratta mat maaro; imagine karo ki browser har tag ko visually kaise draw karta hai.

👨‍🏫3. Teacher Demonstration Code

See how both user profile and top repositories are fetched and populated into the UI.

GitHub API Explorer Architecture with Repo Fetchinghtml
<!DOCTYPE html>
<html>
<head>
  <style>
    body { font-family: 'Segoe UI', sans-serif; background: #060c18; color: #fff; padding: 24px; }
    .card { max-width: 500px; margin: auto; background: #0c1328; border: 1px solid #1e293b; padding: 24px; border-radius: 14px; }
    .search-row { display: flex; gap: 8px; margin-bottom: 20px; }
    input { flex: 1; padding: 10px; background: #060c18; border: 1px solid #334155; color: #fff; border-radius: 6px; }
    button { padding: 10px 16px; background: #2563eb; color: #fff; border: none; border-radius: 6px; font-weight: bold; cursor: pointer; }
    .profile-box { text-align: center; display: none; }
    .avatar { width: 90px; height: 90px; border-radius: 50%; border: 3px solid #2563eb; margin-bottom: 10px; }
    .stats { display: flex; justify-content: space-around; background: #060c18; padding: 12px; border-radius: 8px; margin: 16px 0; }
    .stat-val { font-size: 18px; font-weight: bold; color: #38bdf8; }
    .stat-label { font-size: 11px; color: #94a3b8; }
  </style>
</head>
<body>
  <div class="card">
    <h3>🔍 GitHub Developer Explorer</h3>
    <div class="search-row">
      <input type="text" id="usernameInput" placeholder="Enter GitHub username (e.g., torvalds)" />
      <button id="searchBtn">Search</button>
    </div>
    <div class="profile-box" id="profileBox">
      <img id="avatarImg" class="avatar" src="" alt="Avatar" />
      <h3 id="nameText" style="margin:0;"></h3>
      <p id="bioText" style="color:#94a3b8;font-size:13px;"></p>
      <div class="stats">
        <div><div class="stat-val" id="repoCount">0</div><div class="stat-label">Repos</div></div>
        <div><div class="stat-val" id="followerCount">0</div><div class="stat-label">Followers</div></div>
        <div><div class="stat-val" id="followingCount">0</div><div class="stat-label">Following</div></div>
      </div>
      <a id="profileLink" href="#" target="_blank" style="color:#10b981;font-weight:bold;text-decoration:none;">View on GitHub →</a>
    </div>
    <div id="errorMsg" style="color:#ef4444;text-align:center;display:none;"></div>
  </div>

  <script>
    const searchBtn = document.getElementById("searchBtn");
    const input = document.getElementById("usernameInput");
    const box = document.getElementById("profileBox");
    const err = document.getElementById("errorMsg");

    async function searchUser() {
      const username = input.value.trim();
      if (!username) return;

      box.style.display = "none";
      err.style.display = "none";
      searchBtn.disabled = true;

      try {
        const res = await fetch("https://api.github.com/users/" + encodeURIComponent(username));
        if (res.status === 404) throw new Error("GitHub user '" + username + "' not found.");
        if (!res.ok) throw new Error("API request failed with status " + res.status);

        const data = await res.json();
        document.getElementById("avatarImg").src = data.avatar_url;
        document.getElementById("nameText").textContent = data.name || data.login;
        document.getElementById("bioText").textContent = data.bio || "No bio provided.";
        document.getElementById("repoCount").textContent = data.public_repos;
        document.getElementById("followerCount").textContent = data.followers;
        document.getElementById("followingCount").textContent = data.following;
        document.getElementById("profileLink").href = data.html_url;

        box.style.display = "block";
      } catch (e) {
        err.textContent = e.message;
        err.style.display = "block";
      } finally {
        searchBtn.disabled = false;
      }
    }

    searchBtn.addEventListener("click", searchUser);
    input.addEventListener("keydown", (e) => { if (e.key === "Enter") searchUser(); });
  </script>
</body>
</html>

2. Hands-On Practical Lab: Follow Instructions in VS Code

Code like a professional software engineer! Follow the step-by-step instructions below in Visual Studio Code (VS Code) on your PC, test your output locally, and push to GitHub.

2 Coding Tasks
Interactive Coding TestAuto-Evaluates as you type

Day 39 Practical Task Test Studio

Test Score:1 / 2 Passed
1. Practical Task Specifications & Live Test Checklist:Type code below to pass tests
Task 1Fetch Repositories from GitHub API

Use fetch("https://api.github.com/users/" + user + "/repos?sort=updated&per_page=3") with async/await.

✔ PASSED
Task 2Render Repo Card Elements

Map through the repositories array and display repo.name, repo.language, and repo.stargazers_count.

⏳ WAITING
2. Type HTML & CSS Code:index.html
index.html
⚡ Real-Time Testing Active
Tab inserts 2 spaces • Live DOM refresh299 chars
Live Browser Output:
🔒 http://localhost:5500/index.html
Live
Renders live HTML & CSS typed on the left.
Interactive Bug Detective

Unencoded User Input in URL Bug

Tap or click on the exact line below that contains the error:

Click any code line
⚠️ Broken Code Inspector
Tap buggy line
1
// ❌ Bug: If username contains spaces or special characters, URL breaks!
2
const username = "john doe";
3
fetch("https://api.github.com/users/" + username); // Bad request!
Stuck? Need a detective clue before checking the solution?

Senior Developer Forensic Analysis:

User inputs placed directly into URLs without URI encoding can contain spaces, ampersands, or slashes that corrupt the HTTP request or lead to security vulnerabilities.

Golden Rule: Always validate code syntax and security attributes before pushing to GitHub!

📝Independent Practice: Assignment

📄 index.html

BCA Developer Directory & GitHub Inspector SPA

  • •Build a production-grade GitHub Profile Inspector supporting both light and dark themes.
  • •Fetch user details AND their top 4 most recently updated repositories.
  • •Render repository language tags with color indicators (e.g. JavaScript, HTML, CSS, Python).
  • •Add a "Recently Searched" history bar using localStorage to remember the last 3 searched developers.
Submission Evaluation Criteria: Push index.html, styles.css, and app.js to GitHub under day-39.
Exact Assignment Solution Code: index.html

Open Visual Studio Code on your PC (code .), create index.html, paste this complete step-by-step verified code, test in your browser, and push to your GitHub repo:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>BCA Day 39 - GitHub Inspector</title>
  <style>
    body { font-family: 'Segoe UI', sans-serif; background: #060c18; color: #fff; padding: 24px; }
    .card { max-width: 560px; margin: auto; background: #0c1328; border: 1px solid #1e293b; padding: 24px; border-radius: 14px; }
    .search-box { display: flex; gap: 8px; margin-bottom: 20px; }
    input { flex: 1; padding: 10px; background: #060c18; border: 1px solid #334155; color: #fff; border-radius: 6px; }
    button { padding: 10px 18px; background: #2563eb; color: #fff; border: none; border-radius: 6px; font-weight: bold; cursor: pointer; }
    .profile-card { display: flex; gap: 16px; align-items: center; background: #060c18; padding: 16px; border-radius: 10px; margin-bottom: 16px; }
    .avatar { width: 70px; height: 70px; border-radius: 50%; border: 2px solid #2563eb; }
    .repo-item { background: #1e293b; padding: 12px; border-radius: 8px; margin-bottom: 8px; display: flex; justify-content: space-between; align-items: center; }
    .repo-name { color: #38bdf8; font-weight: bold; text-decoration: none; }
    .star-badge { background: #334155; padding: 2px 8px; border-radius: 12px; font-size: 11px; }
    #output { display: none; }
  </style>
</head>
<body>
  <div class="card">
    <h2>⚡ BCA GitHub Inspector</h2>
    <div class="search-box">
      <input type="text" id="userInput" placeholder="Search developer (e.g., octocat)..." />
      <button id="searchBtn">Inspect</button>
    </div>
    <div id="output">
      <div class="profile-card">
        <img class="avatar" id="avatar" src="" />
        <div>
          <h3 style="margin:0;" id="name"></h3>
          <p style="margin:4px 0;color:#94a3b8;font-size:12px;" id="bio"></p>
          <div style="font-size:12px;color:#10b981;" id="stats"></div>
        </div>
      </div>
      <h4>Top Repositories</h4>
      <div id="reposList"></div>
    </div>
    <div id="errMsg" style="color:#ef4444;text-align:center;display:none;"></div>
  </div>

  <script>
    const btn = document.getElementById("searchBtn");
    const input = document.getElementById("userInput");
    const output = document.getElementById("output");
    const errMsg = document.getElementById("errMsg");

    btn.addEventListener("click", async () => {
      const u = input.value.trim();
      if (!u) return;

      output.style.display = "none";
      errMsg.style.display = "none";
      btn.disabled = true;

      try {
        const [uRes, rRes] = await Promise.all([
          fetch("https://api.github.com/users/" + encodeURIComponent(u)),
          fetch("https://api.github.com/users/" + encodeURIComponent(u) + "/repos?sort=updated&per_page=3")
        ]);

        if (uRes.status === 404) throw new Error("User not found on GitHub");
        if (!uRes.ok) throw new Error("Failed to fetch user");

        const user = await uRes.json();
        const repos = await rRes.json();

        document.getElementById("avatar").src = user.avatar_url;
        document.getElementById("name").textContent = user.name || user.login;
        document.getElementById("bio").textContent = user.bio || "No bio available.";
        document.getElementById("stats").textContent = user.public_repos + " Repositories • " + user.followers + " Followers";

        const reposList = document.getElementById("reposList");
        reposList.innerHTML = "";
        repos.forEach(r => {
          const div = document.createElement("div");
          div.className = "repo-item";
          div.innerHTML = '<a class="repo-name" href="' + r.html_url + '" target="_blank">' + r.name + '</a><span class="star-badge">⭐ ' + r.stargazers_count + '</span>';
          reposList.appendChild(div);
        });

        output.style.display = "block";
      } catch (err) {
        errMsg.textContent = "Error: " + err.message;
        errMsg.style.display = "block";
      } finally {
        btn.disabled = false;
      }
    });
  </script>
</body>
</html>
Verified Assignment Code Solution (100% Tested & Ready to Run)

🎓4. Viva Check: Mandatory Conceptual Test

What is the advantage of using Promise.all([fetch(userUrl), fetch(reposUrl)]) over running them sequentially with two consecutive awaits?

5. Mandatory Step: Push to GitHub to Unlock Next Lesson

Target Repo: html-css-projects

Windows 11 Terminal / VS Code
1$
mkdir day-39
Create a new project folder (day-39)
2$
cd day-39
Change working directory to day-39
3$
git checkout -b feature/day-39-github-explorer
4$
git add index.html
5$
git commit -m "feat(day-39): build dynamic github profile explorer single page application"
Commit staged changes with a descriptive message
6$
git push origin feature/day-39-github-explorer
Push local commits directly to your remote GitHub repository
⌨️ Paste into terminal:Ctrl + V✨ Word wrap active (no horizontal cutoff)
Completion Prerequisites VerificationIncomplete Steps
Google Login
✔ Required
VS Code Implementation
Step 4 Viva Check
Own GitHub Project
Required

Exact GitHub Setup Guide & Expected Structure

Day 39 Requirements

Follow these exact folder and file names to prevent verification errors.

1. GitHub Repository
html-css-projects
Must be set to Public
2. Exact FolderNEW
day-39/ or bca-day-39/
Create inside repo root
3. Exact File NameREQUIRED
index.html
⚠️ No spaces or custom names
4. What to Submit Below
https://github.com/YOU/html-css-projects
Or direct link to index.html
Terminal Commands to Create & Push Day 39
1$
# 1. Enter your repository directory
2$
cd html-css-projects
Change working directory to html-css-projects
3$
# 2. Create the exact folder for Day 39
4$
mkdir day-39
Create a new project folder (day-39)
5$
cd day-39
Change working directory to day-39
6$
# 3. Create your code file: index.html
7$
# (Write your Day 39 homework code inside index.html)
8$
# 4. Save, stage, commit and push to GitHub:
9$
git add .
Stage all modified files and new assets for commit
10$
git commit -m "Day 39: Building a Dynamic GitHub Profile Explorer SPA (Async REST API Mini App)"
Commit staged changes with a descriptive message
11$
git push origin main
Push local commits directly to your remote GitHub repository
⌨️ Paste into terminal:Ctrl + V✨ Word wrap active (no horizontal cutoff)
How to Avoid "Could not find your practical code file" Errors:
1.Use Lowercase index.html: Avoid spaces or custom names like Alan Turing..html or Index.HTML. Linux/GitHub servers are strictly case-sensitive.
2.Separate Day Folders: Create a new folder day-39/ for today so you don't overwrite previous days.
3.Ensure Public Visibility: If your GitHub repo is Private, automated validation cannot inspect your code. Set it to Public.
4.Check on GitHub Website: Before clicking "Verify", open your repo in Google Chrome to confirm your files were pushed to branch main.
📁 github.com/YOUR_USERNAME/html-css-projects
Branch: main
README.md# BCA Practical Portfolio overview
day-01/Day 1 Prior Lesson
└──index.html
day-02/Day 2 Prior Lesson
└──index.html
day-03/Day 3 Prior Lesson
└──index.html
day-04/Day 4 Prior Lesson
└──index.html
day-05/Day 5 Prior Lesson
└──index.html
day-06/Day 6 Prior Lesson
└──index.html
day-07/Day 7 Prior Lesson
└──index.html
day-08/Day 8 Prior Lesson
└──index.html
day-09/Day 9 Prior Lesson
└──index.html
day-10/Day 10 Prior Lesson
└──index.html
└──styles.css
day-11/Day 11 Prior Lesson
└──index.html
day-12/Day 12 Prior Lesson
└──index.html
day-13/Day 13 Prior Lesson
└──index.html
day-14/Day 14 Prior Lesson
└──index.html
day-15/Day 15 Prior Lesson
└──index.html
day-16/Day 16 Prior Lesson
└──index.html
day-17/Day 17 Prior Lesson
└──index.html
day-18/Day 18 Prior Lesson
└──index.html
day-19/Day 19 Prior Lesson
└──index.html
day-20/Day 20 Prior Lesson
└──index.html
└──styles.css
day-21/Day 21 Prior Lesson
└──index.html
day-22/Day 22 Prior Lesson
└──index.html
day-23/Day 23 Prior Lesson
└──index.html
day-24/Day 24 Prior Lesson
└──index.html
day-25/Day 25 Prior Lesson
└──index.html
day-26/Day 26 Prior Lesson
└──index.html
day-27/Day 27 Prior Lesson
└──index.html
day-28/Day 28 Prior Lesson
└──index.html
day-29/Day 29 Prior Lesson
└──index.html
day-30/Day 30 Prior Lesson
└──index.html
└──styles.css
day-31/Day 31 Prior Lesson
└──index.html
day-32/Day 32 Prior Lesson
└──index.html
day-33/Day 33 Prior Lesson
└──index.html
day-34/Day 34 Prior Lesson
└──index.html
day-35/Day 35 Prior Lesson
└──index.html
day-36/Day 36 Prior Lesson
└──index.html
day-37/Day 37 Prior Lesson
└──index.html
day-38/Day 38 Prior Lesson
└──index.html
day-39/✨ CREATE THIS FOLDER FOR TODAY (Day 39)
└──index.htmlMust contain:
Sequential Progression Enforced

You are welcome to read all notes, inspect code snippets, and practice all exercises of Day 39 freely! To officially submit your GitHub repository and unlock subsequent days in your portfolio, please complete Day 38: Async/Await Syntax & Browser fetch() API Fundamentals first.

Complete Day 38 First
Day 38: Async/Await Syntax & Browser fetch() API Fundamentals
WhatsApp
Curriculum & Practical Systems Authored by Er. Manoj Kumar
NextSem Academy • BCA Practical Learning Portal