Wat gaan we maken?

  • Een server die op poort 3000 draait
  • Route / → toont HTML-pagina
  • Route /data → stuurt JSON-data

Structuur van ons project

project/
├─ server.js
├─ public/
│  └─ index.html
└─ data/
   └─ leerlingen.json

Stap 1 — Modules importeren

import http from "http"
import fs from "fs"
import path from "path"

const __dirname = import.meta.dirname

http = server maken
fs = bestanden lezen/schrijven
path = veilige padconstructies

Stap 2 — Server aanmaken

const server = http.createServer((req, res) => {
  // Hier behandelen we elk verzoek
})

req = request (van de browser)
res = response (ons antwoord)

Stap 3 — Luisteren op een poort

server.listen(3000, () => {
  console.log('Server luistert op http://localhost:3000')
})

Poort 3000 is een veelgebruikte testpoort.

Stap 4 — HTML route maken

if (req.method === 'GET' && req.url === '/') {
  const filePath = path.join(__dirname, 'public', 'index.html')
  fs.readFile(filePath, 'utf8', (err, inhoud) => {
    res.statusCode = 200
    res.setHeader('Content-Type', 'text/html; charset=utf-8')
    res.end(inhoud)
  })
}

Stap 5 — JSON route maken

else if (req.method === 'GET' && req.url === '/data') {
  const filePath = path.join(__dirname, 'data', 'leerlingen.json')
  fs.readFile(filePath, 'utf8', (err, inhoud) => {
    res.statusCode = 200
    res.setHeader('Content-Type', 'application/json; charset=utf-8')
    res.end(inhoud)
  })
}

Stap 6 — Foutpagina

else {
  res.statusCode = 404
  res.setHeader('Content-Type', 'text/plain; charset=utf-8')
  res.end('404 - Pagina niet gevonden')
}

Stap 7 — JSON-bestand

{
  "6apda": {
    "Noa": 10,
    "Zakir": 12
  },
  "6inco": {
    "Thomas": 99
  }
}

Stap 8 — HTML-pagina

<h1>Leerlingen</h1>
<button id="btn">Laad data</button>
<div id="output"></div>

Stap 9 — Script toevoegen

<script>
btn.addEventListener('click', () => {
  fetch('/data')
    .then(res => res.json())
    .then(data => {
      console.log(data)
    })
    .catch(err => {
      console.error('Fout bij ophalen:', err)
    })
})
</script>

Stap 10 — Data tonen

fetch('/data')
  .then(res => res.json())
  .then(data => {
    for (const klas in data) {
      const sectie = document.createElement('section')
      const titel = document.createElement('h2')
      titel.textContent = klas
      sectie.appendChild(titel)
      document.body.appendChild(sectie)
    }
  })
  .catch(err => console.error(err))

Stap 11 — Leerlingen in lijst zetten

fetch('/data')
  .then(res => res.json())
  .then(data => {
    for (const klas in data) {
      const sectie = document.createElement('section')
      const titel = document.createElement('h2')
      titel.textContent = klas
      sectie.appendChild(titel)

      const lijst = document.createElement('ul')
      for (const naam in data[klas]) {
        const li = document.createElement('li')
        li.textContent = `${naam} — ${data[klas][naam]}`
        lijst.appendChild(li)
      }

      sectie.appendChild(lijst)
      document.body.appendChild(sectie)
    }
  })
  .catch(err => console.error('Fout:', err))

Stap 13 — Testen

  • Start de server met node server.js
  • Open http://localhost:3000
  • Klik op “Laad data” en kijk in de console en op de pagina

Stap 14 — Wat gebeurt er?

  1. Browser vraagt / → HTML wordt geladen
  2. JS doet fetch('/data') → Promise
  3. Server stuurt JSON terug
  4. Met .then() verwerken we het antwoord

Stap 15 — Wat is een Promise?

Een Promise is een “belofte” dat er later een resultaat zal zijn.

  • .then() → wat te doen als het lukt
  • .catch() → wat te doen als er iets fout gaat

Stap 16 — Samenvatting fetch()

  • fetch() stuurt een HTTP-verzoek
  • .then(res => res.json()) zet JSON om naar object
  • .then(data => ...) gebruikt de data
  • .catch() vangt fouten op

Stap 17 — Hele fetch-keten

fetch('/data')
  .then(res => res.json())
  .then(data => toonData(data))
  .catch(fout => console.error(fout))

Stap 18 — Functie toonData

function toonData(data) {
  for (const klas in data) {
    const sectie = document.createElement('section')
    const titel = document.createElement('h2')
    titel.textContent = klas
    sectie.appendChild(titel)

    const lijst = document.createElement('ul')
    for (const naam in data[klas]) {
      const li = document.createElement('li')
      li.textContent = `${naam} — ${data[klas][naam]}`
      lijst.appendChild(li)
    }

    sectie.appendChild(lijst)
    document.body.appendChild(sectie)
  }
}

Stap 19 — Code is nu duidelijker

De fetch()-keten is kort, en de logica zit in een aparte functie.

Stap 20 — Promise visualisatie

fetch() → Promise
   │
   ├── .then() → OK
   │
   └── .catch() → Fout

Stap 21 — Controleer netwerkverkeer

Open DevTools (F12 → tab “Network”).

Bekijk het verzoek naar /data en het antwoord (JSON).