Kop 1

tagline

JSON importeren en sorteren met JS

JavaScript heeft een mogelijkheid om arrays te sorteren.
Dit gaat ook prima als het een array van objecten betreft.

Leerdoelen

  • kennismaken met sorteren van array's in JavaScript;
  • opfrissen van vaardigheden met array's in JavaScript;
  • opfrissen van asynchrone processen in JavaScript;
  • opfrissen van werken met objecten in JavaScript.

Bron

Een aan te vullen JSON-bestand: https://github.com/Theo-denBlanken/boekJSON

Opdracht

  1. Gebruik het voorbeeld bestand: https://github.com/Theo-denBlanken/boekJSON
  2. Vul dit aan met minstens een eigen boek naar keuze
  3. Voeg ook 2 eigenschappen aan de boeken toe:denk aan genre, prijs
  4. In plaats van alle bovenstaande punten mag je ook een lijst met objecten en eigenschappen maken die je helamaal zelf bedenkt: denk aan CS's, films, favourite YouTube filmpjes

Bekijk de presentatie

Sorteer JSON data in JavaScript 0: het resultaat (00:01:43)

Deze tutorialreeks laat zien hoe je de data uit een JSON-bestand op verschillende eigenschappen kunt sorteren.
Het JSON-bestand wordt gelezen en omgezet naar een JavaScript-object met verschillende eigenschappen. Op elk van die eigenschappen kan dan oplopend of aflopend worden gesorteerd.

Sorteer JSON data in JavaScript 1: JSON inlezen (00:09:17)

Het JSON bestand is een apart bestand.
JavaScript moet dit na het inlezen deze manipuleren. Omdat er dus gewacht moet worden tot het bestand is geladen, moeten we asynchroon gaan werken met AJAX.
We maken daarvoor een XMLHttpRequest-object aan.
Het onreadystatechange event controleert of de readyState van het object 4 is en de state van dit object 200 is. Dan kan de opdracht gegeven worden de responseText uit te voeren.
Om de request uit te voeren roepen we de .open()-method aan van dit object. Deze methode heeft 3 argumenten: "GET", de url van het JSON-bestand en een boolean, die aangeeft of het een asynchroon verzoek is. Dat is bij ons dus true.
Zie: https://developer.mozilla.org/en-US/docs/Glossary/XHR_(XMLHttpRequest) en https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open

Tot slot moet alles worden aangeroepen. Dat doen we dan met met de .send()-method van het XMLHttpRequest-object.

We zorgen er ook voor dat alle JSON-data in het HTML-document wordt uitgevoerd.

Sorteer JSON data in JavaScript 2: data weergeven (00:10:52)

De grote JSON-string die is uitgevoerd, moet een net overzicht worden.
De onnodige log's worden verwijderd. De samenhang tussen de eigenschappen binnen de objecten, kan het best behandeld worden als het objecten worden met eigenschappen.
Ook is het praktisch als er 1 groot object komt met een eigenschap data en een method uitvoeren. Daarvoor herschikt worden.
We maken dus een groot object in dit geval sorteerBoekObj met een data-eigenschap die nog leeg is en een uitvoeren-methode, die in plaats van de responseText de data van het sorteerBoekObj uitvoert.
Die dat wordt gevuld vanuit de onreadystatechange: sorteerBoekObj.data = this.responseText;

Bovendien moet daar de funktie sorteerBoekObj.uitvoeren(); worden uitgeroepen, en dat zie dezelfde tekst verschijnen, maar op een andere manier tot stand gekomen.
Nu ontstaat de mogelijkheid om de responseText om te zetten naar objecten: JSON.parse();
De uitvoer is dan gelijk anders: Objecten!
Aangezien het een array is weten we er wel raad mee: met een for-lus wordt uit ieder object de titel eigenschap opgevraagd.
Met een br-elementje voeg je die in iedere lus toe en het resultaat is een lijst van titels.
Desgewenst maak je door naar een andere eigenschap te kijken er auteurs van.

Sorteer JSON data in JavaScript 3: array's sorteren (00:07:21)

In dit belangrijke tussenfilmpje gaan we in de console van de browser JS invoeren om te zien hoe je daarmee arrays kunt sorteren.
JavaScript heeft een eigen method .sort() om de inhoud van een array te sorteren.
Het blijkt dat deze de inhoud als een string oplopend sorteert.
Dat is niet altijd de bedoeling.
Daarom kun je een functie als argument in de sort-methode meegeven.
Als je bijvoorbeeld getallen sorteert, dan kijk je naar de uitkomst van verschil 2 opeenvolgende items in het gehoopte resultaat. Als deze positief is, verloopt de sortering als gewenst, als deze negatief is wordt alles omgekeerd.
Zo zal .sort( (a,b) => a-b>0 ? 1 : -1 ) een array met getallen oplopend sorteren.
Dit is de verkorte notatie. De funktie wordt met fat-arrow notatie gebruikt en de if-conditional heeft een ternary notatie gekregen.
Ook zie je hoe je kunt sorteren op een eigenschap van de items, in dit geval de lengte van de strings.

Sorteer JSON data in JavaScript 4: objecten sorteren (00:05:23)

In het sorteerBoekObj wordt een method sorteren() toegevoegd. Deze wordt dan van uit de xmlhttp.onreadychange aangeroepen.
Na het sorteren roept deze method op zijn beurt weer de uitvoer-methode aan met this.uitvoeren().
Omdat hij zelf in sorteerBoekObj zit kan hij de eigenschap data aanroepen met this.data.
Het wordt dan
this.data.sort( (a,b) => a.eigenschap > b.eigenschap ? 1 : -1 );
De eigenschap kan dan auteur[0] zijn of titel. De sorteervolgorde wordt met de wissel van 1 en -1 omgekeerd.

Sorteer JSON data in JavaScript 5: alle data in een tabel (00:17:00)

Van elke object-eigenschap kunnen we de data uitvoeren.
Hier wordt hier voor een tabel Om code te kunne hergebruiken maken we een functie, die een tabelkop kan uitvoeren.
Een string variabele wordt voor elk item in de array uitgebreid met het item voorafgegaan door de openingstag van het th-element en gevolgd door de sluit-tag van dat th-element.
Dat kan met een for-lus, maar het is ook goed om te oefenen met een .forEach() lus-methode:
arr.forEach( (item) => { ....... });
We roepen deze functie met een array van de gewenste kop-elementen.
Vervolgens maken we een gelijkluidende functie voor het maken van tabelrijen.
Ook deze is aan te roepen in de uitvoer-method, maar dan met een array van de eigenschappen van objecten.
Voor de afbeelding maken we de gewenste afbeeldingsmarkup eerst in een variabele, die dan in het array kan om in de tabelrij te worden opgenomen.

Sorteer JSON data in JavaScript 6: tabel optimaliseren en stijlen (00:10:54)

Bij de bouw van de tabel zijn wat foutjes binnengeslopen: de tabelrijeen werden niet afgesloten, en er wordt een titel opgeroepen waar een auteur gewenst is.
Daarnaast kan de weergave voor de developer optimaler worden door de items in de lange array's onder lekar te plaatsen.
Voor de geringe styling geven we de tabel en de elementen daarin class-namen volgens de BEM naamconventie. In dit geval: .boekSelectie, .boekSelectie__cover, .boekSelectie__rij, .boekSelectie__data-cel.
WE zorgen voor afwisselende achtergrondkleuren in de rijen met :nth-child(even) pseudoclass. De data hebben wat padding en zijn bovenin de cell geplaatst.

Sorteer JSON data in JavaScript 7: afwisselende rijen met modifier (00:07:13)

De oplossing om rijen afwisselend van een stijl te voorzien is opgelost met een :nth-child selectie in CSS. Het is ook mogelijk een BEM modifier class mee te geven en die dan met JS toe te voegen.
De functie om rijen te maken krijgt dat en extra boolean parameter naast de array.
Afhankelijk van de waarde van de parameter krijgt de CSS wel of niet de --accent modifier mee.
In de method .uitvoeren() maken we dan ook een boolean aan, die true wordt als de iterator modulus 2 gelijk aan 0 is. i%2 geeft de rest als je i door 2 probeert te delen.

Sorteer JSON data in JavaScript 8: objecteigenschap anders aanroepen (00:06:03)

We willen de tabel op andere kenmerken kunnen sorteren.
In het script moet dan in de sorteerfunctie a.titel worden aangepast naar a.auteur of a.taal enzovoorts. Omdat met script te kunnen doen, maken we gebruik van een anderen manier van het aanroepen van objecteigenschappen. Zie hiervoor: https://www.w3schools.com/js/js_objects.asp. Je kunt de eigenschap titel van a niet alleen met a.titel aanroepen maar ook met a.["titel"]. In deze tweede notatie staat de titel als een string genoteerd. Deze tweede notatie wort ook wel een associatieve array genoemd.
Die string kan op zijn beurt natuurlijk als een variabele geschreven.
Daarvoor voegen we de eigenschap kenmerk toe aan sorteerBoekObj. Deze initiƫren we op titel, maar we kunnen dan elke eigenschap van het data-object gebruiken om te sorteren.
Het kenmerk van het sorteerBoekObj gaan we in het volgende filmpje aanpasbaar maken met een select-input.

Sorteer JSON data in JavaScript 9: gebruiker selecteert sorteerkenmerk (00:06:03)

Om sorteerBoekObj.kenmerk door de gebruiker om te laten selecteren, maken we in de html-pagina een select element met een id en de mogelijke opties.
De id gebruiken we in het script om het select-object te selecteren en er een event-listener aan te koppelen.
Bij het change-event, wordt van de target de waarde opgevraagd en toegekend aan sorteerBoekObj.kenmerk. Vervolgens wordt er opnieuw gesorteerd door de bijpassende method aan te roepen.

Sorteer JSON data in JavaScript 10: datumObject invoegen (00:20:06)

De datum van uitgaves zijn nu strings en dat sorteert fout. Helaas is de datum dus in een verkeerd format ingevoerd. Met JS gaan we daar een correct datum-object aan toevoegen.
Eerst maken we een .split() functie, die van de string met spatie een array maakt van 2 strings.
Een andere functie geeft van elke maand een nummer tussen 0 en 11 terug. Dat hebben we nodig om een goed data-object te maken.
Met datum = new Date(); kunnen we een datum-object maken. Dat kan met 2 argumenten: eerst jaar en tweede maandnummer. Test dit in de console uit.

Dit gereedschap gebruiken we door in ons sorteerBoekObj een method te maken, die met een lus door de data gaat, en daar een eigenschap aan toevoegt: de datum in het date-format.
Deze method roepen we aan nadat de data uit de JSON in de data-eigenschap zijn gestopt en voordat er gesorteerd wordt. Controleer weer het sorteerBoekObj in de console en ga na of de eigenschap er is.

Sorteer JSON data in JavaScript 11: op datum sorteren (00:01:50)

Met deze echte datum eigenschap in het object, kunnen we nu eenvoudig op datum sorteren. We passen de value aan in de select-option. Deze stond op uitgave, maar komt nu op de naam van de eigenschap. Immers als deze optie gekozen wordt, komt deze naam in de kenmerk-eigenschap en zal de data op die eigenschap gesorteerd worden.
Voor de uitvoer kunnen we gewoon gebruik blijven maken van de uitgave-eigenschap omdat dit voor de gebruiker er goed uitziet.

Sorteer JSON data in JavaScript 12: auteurs opsommen (00:07:06)

In de JSON worden de auteur(s) in een array-notatie weergeven. We verwerken tot nu toe alleen de eerste.
Om alle auteurs en coauteurs weer te kunnen geven, maken we een aparte functie, die de array omzet in een opsomming met op de juiste plaats een komma en bij de voorlaatste de tussenvoeging ' en '.
We gebruiken daarvoor een JavaScript switch.
Met deze functie maken we in de loop een string die we als argument in de array voor de tabelrij invoeren.

Sorteer JSON data in JavaScript 13: op en aflopend sorteren (00:07:26)

Gebruikers willen soms oplopend dan weer lopend sorteren.
Daarvoor maken we dan 2 radiobuttons met gelijke naam en 1 en -1 als values.
In de sorteer-functie hebben we de volgorde immers laten bepalen door de waarden 1 en -1.
Als we die bij oplopend vermenigvuldigen met 1 blijven ze 1 en -1, maar als we ze allebei vermenigvuldigen met -1 worden ze omgekeerd: -1 en 1.
We maken in sorteerBoekObj dus een eigenschap oplopend die de waarde 1 heeft.
Als er op de radiobuttons wordt geklikt, wordt deze omgezet naar -1.
Roepen we de sorteerfunctie daarna weer aan, dan wordt de sorteervolgorde omgekeerd.
Je kunt de sorteerBoekObj.oplopend bij een klik gelijk maken aan e.target.value. Voor de zekerheid zetten we de string met parseInt(); om naar een getal.

Bonusopdracht

Er zijn de volgende uitdagingen waaruit je kunt kiezen:

  • De auteurs zijn op voornaaam gesorteerd. Pas (evenur=teel ook de JSON) aan zodat wel de naam wordt weergegven als voor- en achternaam, maar gesorteerd op achternaam.
  • voer het geheel niet uit als een (afwisselende) tabel maar meer als de weergave op https://www.bol.com/nl/l/boeken/N/8299/?promo=books-intl_360__A_29683-44295-alle-boeken_1_ waarbij de afbeelding links staat en de relavante info ) inclusief prijs in een vergelijkbare sorteerbare weergave. Dus wel met radio en select-opties voor de gebruiers.


Inleveren

  • Na afloop plaats je deze training online in je bewijzenmap;
  • Valideer jouw pagina's op Markup Validation Service van W3C.
  • De validatie icoontjes staan al in de footer. Code vind je bij https://github.com/Theo-denBlanken/validatie-W3C;
  • Plaats jouw uitwerking op in een aparte repository op GitHub
  • Maak in jouw GitHub-repo een README.md met daarin temnminste een link naar jouw online uitwerking.
  • Plaats de GitHub-link in ELO Magister.