← Module 2: Programming for the Web
Inquiry Question 2: How can data be better visualised using a web browser?
Use JavaScript in the browser to manipulate the DOM, handle events and make asynchronous requests
A focused answer to the HSC Software Engineering Module 2 dot point on client-side JavaScript. DOM manipulation, event handlers, fetch and async/await, the worked example, and the traps markers look for.
Have a quick question? Jump to the Q&A page
What this dot point is asking
NESA wants you to use JavaScript in the browser to read and modify the DOM, respond to user events, and make asynchronous HTTP requests with fetch. You need to write working code under exam conditions.
The answer
Selecting elements (DOM access)
The DOM (Document Object Model) is a tree representation of the HTML document. JavaScript reads and modifies it through methods like:
const heading = document.querySelector("h1");
const buttons = document.querySelectorAll("button.primary");
const username = document.getElementById("username");
Modifying the DOM
Common operations:
heading.textContent = "Welcome";
heading.classList.add("highlighted");
heading.style.color = "blue";
const newItem = document.createElement("li");
newItem.textContent = "New point";
document.querySelector("ul").appendChild(newItem);
document.querySelector(".old").remove();
Use textContent when inserting user-controlled strings. innerHTML parses and executes HTML, which can introduce XSS.
Events
JavaScript responds to user actions through event listeners:
const button = document.querySelector("#save");
button.addEventListener("click", (event) => {
console.log("Saved at", event.timeStamp);
});
const form = document.querySelector("form");
form.addEventListener("submit", (event) => {
event.preventDefault();
// ... custom handling, e.g. validation ...
});
Common events: click, submit, input, change, keydown, mouseover, load.
Asynchronous requests
Browser JavaScript exchanges data with the server through the fetch API, which returns a Promise that resolves with the response. Combined with async and await, this lets you write asynchronous code that reads like synchronous code, with try/catch for error handling.
async function loadUsers() {
const response = await fetch("/api/users", {
headers: { "Accept": "application/json" },
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return response.json();
}
// Use it:
loadUsers()
.then(users => console.log(users))
.catch(err => console.error(err));
Putting it together
A complete example - a search-as-you-type input:
<input id="search" placeholder="Search...">
<ul id="results"></ul>
const input = document.getElementById("search");
const results = document.getElementById("results");
let timeout = null;
input.addEventListener("input", () => {
clearTimeout(timeout);
timeout = setTimeout(async () => {
const q = encodeURIComponent(input.value);
const response = await fetch(`/api/search?q=${q}`);
const items = await response.json();
results.innerHTML = "";
for (const item of items) {
const li = document.createElement("li");
li.textContent = item.title;
results.appendChild(li);
}
}, 300);
});
The 300 ms debounce prevents a request on every keystroke. encodeURIComponent safely encodes user input for use in a URL.
Variables, types, control flow
JavaScript essentials:
const greeting = "Hello"; // immutable binding
let counter = 0; // mutable binding
counter += 1;
const numbers = [1, 2, 3, 4];
const doubled = numbers.map(n => n * 2); // [2, 4, 6, 8]
const even = numbers.filter(n => n % 2 === 0); // [2, 4]
const sum = numbers.reduce((acc, n) => acc + n, 0); // 10
function greet(name) {
if (!name) return "Hello, stranger";
return `Hello, ${name}`;
}
Security: never inject untrusted HTML
Setting innerHTML with a value that came from user input is one of the most common ways an XSS vulnerability slips into a front-end. The browser parses the assigned string as HTML, so any script tag, event handler attribute, or javascript URL inside it can execute. Use textContent or the DOM API instead.
// BAD - XSS risk
container.innerHTML = `<p>${userInput}</p>`;
// GOOD
const p = document.createElement("p");
p.textContent = userInput;
container.appendChild(p);
Past exam questions, worked
Real questions from past NESA papers on this dot point, with our answer explainer.
2025 HSC5 marksWrite JavaScript that, when a button is clicked, fetches a list of users from /api/users and displays each user's name in an unordered list.Show worked answer →
<button id="load">Load users</button>
<ul id="users"></ul>
const button = document.getElementById("load");
const list = document.getElementById("users");
button.addEventListener("click", async () => {
try {
const response = await fetch("/api/users");
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const users = await response.json();
list.innerHTML = "";
for (const user of users) {
const item = document.createElement("li");
item.textContent = user.name;
list.appendChild(item);
}
} catch (err) {
list.innerHTML = `<li>Error: ${err.message}</li>`;
}
});
Walkthrough: select the button and the list with getElementById, attach a click handler with addEventListener, fetch the JSON over HTTP, and rebuild the list. await pauses inside the async function until the response and JSON parse complete. Setting textContent (not innerHTML) prevents XSS if a user name happens to contain HTML.
Markers reward a real event listener (not inline onclick), fetch with await, error handling for non-2xx responses, and use of textContent rather than innerHTML for user-controlled data.
Related dot points
- Construct front-end pages using HTML for structure and CSS for presentation, including semantic markup and responsive design
A focused answer to the HSC Software Engineering Module 2 dot point on HTML and CSS. Semantic markup, the box model, responsive design with media queries, the worked example, and the traps markers look for.
- Design and consume RESTful APIs that exchange JSON, including resource modelling, request methods and status codes
A focused answer to the HSC Software Engineering Module 2 dot point on REST APIs. Resource modelling, JSON, HTTP methods mapped to CRUD, status codes, the worked example, and the traps markers look for.
- Identify and mitigate cross-site scripting (XSS), cross-site request forgery (CSRF) and SQL injection vulnerabilities
A focused answer to the HSC Software Engineering Module 2 dot point on web vulnerabilities. XSS (stored and reflected), CSRF, SQL injection, mitigations for each, the worked example, and the traps markers look for.