Zo pak je elke opdracht aan

Het lastigste van een opdracht is vaak niet de code, maar beginnen. Je kijkt naar een leeg bestand en weet niet welke regel eerst. Dat is normaal. Gebruik dit stappenplan:

  1. Lees de comments in je bestand. Die zijn je to-do-lijst. Elke comment is één klein taakje.
  2. Zeg in gewone taal wat er moet gebeuren. Bijvoorbeeld: "Voor elke gebruiker maak ik een kaartje." Nog geen code!
  3. Vertaal woorden naar JavaScript. "Voor elke" = een loop. "Als … dan" = if. "Bij een klik" = een event listener. "Alleen de …" = .filter().
  4. Begin met één console.log(). Check wat er écht in je variabele zit, voordat je er iets mee doet.
  5. Doe één klein stukje, en test meteen. Sla op, ververs de browser, kijk in de console. Werkt het? Pas dan het volgende stukje.

Tip: de woorden-vertaaltabel

Let op: schrijf niet eerst 30 regels en test dan pas. Als het dan niet werkt, weet je niet waar het misgaat. Kleine stapjes, steeds testen.

Data meegeven aan een functie

Een functie is een recept. Een parameter is een lege plek in dat recept, die pas wordt ingevuld als je de functie aanroept.

const boeken = [
  { titel: 'Harry Potter', genre: 'fantasy' },
  { titel: 'De Hobbit',    genre: 'fantasy' },
  { titel: 'Sapiens',      genre: 'non-fictie' },
];

// "lijst" is de parameter: een lege plek
const toonBoeken = (lijst) => {
  console.log(lijst);
};

// Pas hier wordt "lijst" ingevuld:
toonBoeken(boeken);                // lijst = alle 3 de boeken
toonBoeken([boeken[0]]);           // lijst = alleen Harry Potter

De functie toonBoeken weet niet welke boeken hij krijgt. Hij toont gewoon wat hij krijgt. Daardoor kun je dezelfde functie voor álle boeken én voor een selectie gebruiken.

Twee functies, twee taken

In veel opdrachten werk je met twee functies die samenwerken. De ene kiest welke data, de andere toont het:

Gebruiker kliktEvent listener zet een variabele, bijv. filter = 'fantasy'
→
Kiezer-functieKijkt naar de variabele en maakt de juiste lijst
→
Toon-functieKrijgt de lijst als parameter en zet hem op de pagina

Verwarrend: de parameter heet hetzelfde als de array

Soms staat er const showUsers = (users) => { ... } terwijl er bovenaan ook een array users staat. Binnen de functie bedoelt JavaScript dan de parameter: de lijst die je meegaf bij het aanroepen. Dat kan dus ook een kleinere, gefilterde lijst zijn. Twijfel je? Zet console.log(users) bovenaan in de functie en kijk wat er binnenkomt.

Week 6 · Objecten

Gebruikersbeheer — voordat je begint

  1. Open index.html en zoek deze id's op. Die heb je in je JavaScript nodig:

    • #users — hier komen de kaartjes
    • #filter-admin en #filter-all — de twee knoppen
    • #user-form — het formulier
    • #name, #email, #role — de invoervelden
  2. Open de console met F12 (Mac: Cmd + Option + J). Laat die de hele opdracht open staan.

Hoe hangt alles samen?

Knop / formulierVerandert filter of de array, en roept filterUsers() aan
→
filterUsers()Kiest welke gebruikers en geeft die lijst aan showUsers()
→
showUsers(lijst)Maakt van elke gebruiker in de lijst een kaartje
Week 6 · Stap 1

Gebruikers tonen

Dit staat in je script.js
const showUsers = (users) => {
  // Gebruik destructuring voor elke user: const { name, email, role, active } = user
  // Toon elke user als een <article> in #users
};

Zo maak je daar code van:

  1. Ga naar de functie showUsers(users). Alle code van stap 1 schrijf je binnen deze functie, onder de comments.

  2. Zet in de functie filterUsers() tijdelijk deze regel, zodat je resultaat ziet:

    showUsers(users);

    Onderaan je bestand wordt filterUsers() aangeroepen. Die roept nu jouw showUsers aan. In stap 2 maak je filterUsers af.

    ✔ Test: zet console.log(users) in showUsers. Zie je 4 objecten in de console?

  3. Maak een verwijzing naar het element met id users en sla die op in een variabele, bijvoorbeeld container.

    const container = document.querySelector('#___');
  4. Maak de container leeg (nog steeds boven de loop).

    container.innerHTML = '';

    Waarom? Straks roep je showUsers bij elke klik opnieuw aan. Zonder deze regel komen de kaartjes er steeds bij.

  5. Maak een for...of loop door users. Noem één item in de loop user.

    for (const user of ___) {
    
    }

    ✔ Test: zet console.log(user) in de loop. Zie je 4 losse logs?

  6. Haal in de loop met destructuring name, email, role en active uit user. Deze regel staat al in de comment, je mag hem overnemen.

    const { name, email, role, active } = user;

    ✔ Test: console.log(name). Zie je 4 namen?

  7. Maak in de loop, onder de destructuring, een variabele status. Is active true, dan wordt het 'Actief'. Anders 'Inactief'. Gebruik een if / else.

    Waarom in de loop? Elke gebruiker heeft zijn eigen active. Dus voor elke gebruiker moet je opnieuw bepalen wat de status is. Buiten de loop bestaat active niet eens.

    Waarom überhaupt? Als je active direct op je kaartje zet, staat er letterlijk true of false.

  8. Voeg in de loop, onder de if / else, met += een <article> toe aan de container. Gebruik backticks ` en ${ } om je variabelen erin te zetten.

    container.innerHTML += `
      <article>
        <h3>${name}</h3>
        <!-- zet hier ook email, role en status neer -->
      </article>
    `;

Waar staat wat?

Wat maar één keer hoeft, staat boven de loop. Wat per gebruiker anders is, staat in de loop.

const showUsers = (users) => {
  // stap 3: verwijzing naar #users     → 1 keer, boven de loop
  // stap 4: container leegmaken        → 1 keer, boven de loop

  for (const user of users) {
    // stap 6: destructuring            → per gebruiker, in de loop
    // stap 7: if / else voor status    → per gebruiker, in de loop
    // stap 8: <article> toevoegen      → per gebruiker, in de loop
  }
};

Klaar als: je 4 kaartjes ziet met naam, e-mail, rol en "Actief" of "Inactief".

Werkt het niet?

  • Je ziet niks: staat stap 2 (showUsers(users) in filterUsers) erin? En staat filterUsers() nog onderaan je bestand?
  • undefined op je kaartje: spelfout in de destructuring. Name is niet hetzelfde als name.
  • Fout met null in de console: het id in je querySelector klopt niet. Vergeet de # niet.
Week 6 · Stap 2

Filteren op rol

Eerst maak je filterUsers af, daarna de twee knoppen.

A. De functie filterUsers

Dit staat in je script.js
const filterUsers = () => {
  // Als filter 'admin' is, toon alleen gebruikers met role === 'admin'
  // Anders toon je alle gebruikers
  // Roep showUsers() aan met de gefilterde lijst
};

Zo maak je daar code van:

  1. Ga naar de functie filterUsers() en haal de tijdelijke regel showUsers(users); uit stap 1 weg.

  2. Maak een if / else die checkt of de variabele filter gelijk is aan 'admin'.

    if (filter === 'admin') {
    
    } else {
    
    }

    Let op: drie === om te vergelijken. Met één = verander je de waarde.

  3. Maak in de if een nieuwe variabele admins. Gebruik .filter() op users om alleen de gebruikers te houden met role 'admin'.

    const admins = users.filter(user => user.___ === '___');

    filter (jouw variabele, onthoudt welke knop is ingedrukt) en .filter() (array-methode, maakt een nieuwe lijst) zijn twee verschillende dingen.

  4. Roep in de if de functie showUsers aan en geef admins mee als parameter.

    Hier zie je waarom showUsers een parameter heeft: je kunt hem elke lijst geven die je wilt.

  5. Roep in de else de functie showUsers aan met de hele lijst users.

    ✔ Test: verander bovenaan tijdelijk let filter = 'admin'. Zie je alleen Jan en Sara? Zet hem daarna terug op 'all'.

B. De twee knoppen

Dit staat in je script.js
// Maak een eventlistener voor de #filter-admin button
// Zet filter op 'admin' en roep filterUsers() aan

// Maak een eventlistener voor de #filter-all button
// Zet filter op 'all' en roep filterUsers() aan

Zo maak je daar code van:

  1. Maak een verwijzing naar #filter-admin en voeg een click event listener toe.

    document.querySelector('#___').addEventListener('click', () => {
    
    });

    ✔ Test: zet console.log('klik') in de listener en klik op de knop.

  2. Zet in de listener de variabele filter op 'admin'.

  3. Roep daarna in de listener filterUsers() aan.

  4. Doe stap 1 t/m 3 nog een keer voor de knop #filter-all, maar zet filter nu op 'all'.

Klaar als: "Admins" alleen Jan en Sara laat zien, "Alle" weer alle 4, en er na veel klikken geen dubbele kaartjes zijn.

Werkt het niet?

  • Kaartjes worden steeds meer: je bent stap 1.4 vergeten (container.innerHTML = '').
  • Assignment to constant variable: bovenaan moet let filter staan, niet const.
Week 6 · Stap 3

Gebruiker toevoegen

Dit staat in je script.js
// Maak een eventlistener voor het #user-form submit event
// Lees naam, email en role uit de invoervelden
// Maak een nieuw user object aan met spread op een default object
// Voeg toe aan de array en roep filterUsers() aan

Zo maak je daar code van:

  1. Maak boven de event listener een default object (dit staat niet in de comments, die maak je zelf), bijvoorbeeld defaultUser. Geef het dezelfde properties als de andere gebruikers: name, email, role en active.

    De beginwaarden bedenk je zelf. Vraag jezelf af: is een nieuwe gebruiker actief? Wat is een logische standaardrol?

  2. Maak een verwijzing naar #user-form en voeg een submit event listener toe. Zet e tussen de haakjes van de functie.

    document.querySelector('#___').addEventListener('submit', (e) => {
    
    });

    Let op: de listener zit op het formulier, niet op de knop.

  3. Zet als eerste regel in de listener:

    e.preventDefault();

    Waarom? Een formulier herlaadt standaard de pagina. Dan ben je alles kwijt.

  4. Lees in de listener de waarden van #name, #email en #role uit met .value.

    document.querySelector('#name').value

    Doe dit binnen de listener. Erbuiten lees je de velden bij het laden van de pagina, en dan zijn ze nog leeg.

    ✔ Test: log de drie waarden en verstuur het formulier. Zie je wat je hebt ingetypt?

  5. Maak een nieuw object newUser. Zet eerst ...defaultUser erin (spread), en overschrijf daarna name, email en role met de ingevulde waarden.

    const newUser = {
      ...defaultUser,
      name: ___,
      email: ___,
      role: ___,
    };

    De volgorde is belangrijk: wat onderaan staat wint. Dus eerst de spread, dan jouw waarden.

    ✔ Test: console.log(newUser). Heeft hij alle 4 de properties?

  6. Voeg newUser toe aan de array users met .push().

  7. Roep filterUsers() aan om de lijst te verversen.

    Waarom niet showUsers()? Dan negeer je het filter dat aan staat. filterUsers() houdt er rekening mee.

  8. Bonus: maak het formulier leeg na het toevoegen met .reset() op het formulier.

Klaar als: er na het versturen een nieuw kaartje bij komt, de pagina niet herlaadt en het kaartje ook een status heeft.

Werkt het niet?

  • Pagina flitst en alles is weg: e.preventDefault() vergeten, of e staat niet tussen de haakjes.
  • Leeg kaartje: je leest .value buiten de listener.
  • [object HTMLInputElement] op je kaartje: je bent .value vergeten.

Nog steeds vast?

Loop dit lijstje af voordat je hulp vraagt. Vaak vind je het zelf, en anders kun je je vraag veel beter stellen.

  1. Staat er iets roods in de console? Lees de eerste regel en zoek hem op bij Foutmeldingen.
  2. Geen fout, maar het doet niks? Zet console.log() op meerdere plekken. Waar stoppen de logs? Daar zit het probleem.
  3. Leg je code hardop uit, regel voor regel, aan een klasgenoot (of aan een badeendje). Vaak hoor je jezelf dan zeggen waar het misgaat.
  4. Zoek de term op in de zoekbalk van de cheat sheet.
  5. Vraag hulp en vertel daarbij: wat je wilde, wat je deed, en wat er gebeurde (met de foutmelding erbij).