Unit 1 · Module 3

The Lifecycle of a Click

What happens from finger on screen to data in database

In Module 2, we said "JavaScript is what catches the click." Now let's walk through what actually happens, step by step, with everything you know — variables, functions, types, all of it working together.

A user has filled out an intake form and clicks the Submit button. Here's what JavaScript does, in order.

Step 1: The event fires

The browser is always listening. When the user clicks that button, the browser creates an event — a small object that describes what just happened.

The browser automatically creates something like this

{
  type: "click",
  target: submitButton,
  timeStamp: 1712438400000
}

That object gets handed to JavaScript. This is the starting gun.

Step 2: The event handler runs

Somewhere in your code, a developer connected a function to that button. "When this button is clicked, run this function." That connection was made when the page first loaded:

Connecting a function to a button

submitButton.addEventListener("click", handleSubmit)

Translation: "Dear browser — when someone clicks submitButton, call the function named handleSubmit."

addEventListener is how your code communicates to the browser which events it cares about. The browser has been holding onto that instruction since the page loaded. Now the click happened. So it calls handleSubmit.

Step 3: The function gathers the variables

handleSubmit starts running. First thing — gather up all the data the user typed. Those form fields have been sitting in the browser the whole time the user was filling things out:

Gathering form data into one variable

function handleSubmit() {
  let formData = {
    firstName: firstNameInput.value,
    lastName: lastNameInput.value,
    email: emailInput.value,
    caseType: caseTypeDropdown.value,
    phone: phoneInput.value
  }
}

Every .value reads what the user typed into that field. All of those values get bundled into one object called formData. This is the moment where individual pieces of information get collected into one organized package.

Step 4: Validation — checking the data

Before sending anything anywhere, JavaScript checks if the data is good. This isn't type-checking — it's rule-checking. Are the required fields filled in?

Validation with conditionals

  if (!formData.firstName) {
    showError("First name is required")
    return
  }

  if (!formData.email) {
    showError("Email is required")
    return
  }

The if keyword is a conditional — a built-in JavaScript structure that checks a condition and runs code only if that condition is true. It's not a function. It's one of those bottom-layer built-in keywords like return and let.

The ! means "not." So !formData.firstName means "if firstName is not present or is empty."

Step 5: The API call — sending data to the server

If validation passes, JavaScript sends the data out of the browser:

Sending data to the server

  let response = await fetch("/api/lead-intake", {
    method: "POST",
    body: JSON.stringify(formData)
  })

Let's break this one line apart — there's a lot happening:

This is the moment data leaves the browser. fetch is a built-in JavaScript function — one of the few, like typeof. It sends an HTTP request to your server. HTTP is the protocol — the agreed-upon format — for how browsers and servers communicate. The http:// in URLs tells the browser "use this protocol."

Step 6: The server responds

The backend (your API route at /api/lead-intake) receives the data, saves it to the database, and sends back a response:

Receiving the response

  let result = await response.json()

The server sent back JSON. .json() converts it from text back into a JavaScript object. Now result is a variable holding whatever the server decided to send back — maybe { success: true, leadId: 247 }.

Step 7: The UI updates

Based on what came back, JavaScript updates what the user sees:

Updating the screen

  if (result.success) {
    showConfirmation("Your intake form has been submitted!")
    clearForm()
  } else {
    showError("Something went wrong. Please try again.")
  }

Another conditional. If the server said success, show a confirmation and clear the form. If not, show an error. showConfirmation and clearForm are functions — each one is a named set of instructions defined somewhere else.

The full function — all seven steps

handleSubmit — the complete lifecycle

async function handleSubmit() {
  // Step 3: Gather variables
  let formData = {
    firstName: firstNameInput.value,
    lastName: lastNameInput.value,
    email: emailInput.value,
    caseType: caseTypeDropdown.value,
    phone: phoneInput.value
  }

  // Step 4: Validate
  if (!formData.firstName) {
    showError("First name is required")
    return
  }
  if (!formData.email) {
    showError("Email is required")
    return
  }

  // Step 5: Send to server
  let response = await fetch("/api/lead-intake", {
    method: "POST",
    body: JSON.stringify(formData)
  })

  // Step 6: Receive response
  let result = await response.json()

  // Step 7: Update UI
  if (result.success) {
    showConfirmation("Your intake form has been submitted!")
    clearForm()
  } else {
    showError("Something went wrong. Please try again.")
  }
}

The async keyword on the function means "this function does something that takes time — like talking to a server — and needs to wait for responses." That's why await appears inside it. They're a pair: async on the function, await at the specific moments where waiting happens.

Everything from this module in one function

Every concept from Module 3 is in that function:

The chain of locations

Three different computers are involved in this lifecycle. The user's, the server's, and the database's.

  1. Browser (user's device) — JavaScript collects form data into variables, calls fetch
  2. Internet — HTTP message travels from user's browser to the server
  3. Server (Vercel's computer) — API route code runs, talks to database
  4. Database (Supabase's computer) — data gets saved
  5. Server — API route creates a response
  6. Internet — response travels back
  7. Browser — JavaScript receives response, puts it in a variable, updates the screen

That whole round trip happens in milliseconds. Every click. Every submit. Every save.