-
Notifications
You must be signed in to change notification settings - Fork 0
Journal
Table of Content
Wat ik heb geleerd in deze twee weken is vooral het herontdekken van gestructureerd werken en chainen van functies. Dit omdat ik gauw zelf code schrijf dat hardcoded in elkaar zit om te loopen in een loop in een loop, wat eigenlijk gewoon bad practices zijn. Functional programming paradigm heeft mij vooral geholpen om code in kleinere stukjes te hakken, waardoor de resultaat schoner is, herbuikt kan worden maar ook makkelijker te lezen valt.
- Meer begrip wat fetch en async doet.
- fetch is een browser API dat het handelen van netwerk requests (of asynchrone code) een stuk simpeler maakt om te lezen, wel is het van belang wat fetch doet, oftewel een promise. Async/Await is een feature dat ES8 met zich meebracht om callbacks als het ware te versimpelen.
//fetch async await async getListing = () => { const response = await fetch(`https://api.themoviedb.org/3/movie/now_playing?api_key=${process.env.API_KEY}`); const data = await response.json(); console.log(data); } //fetch .then .catch fetch(`https://api.themoviedb.org/3/movie/now_playing?api_key=${process.env.API_KEY}`) .then(response => response.json()) .then(data => console.log(data));
- fetch is een browser API dat het handelen van netwerk requests (of asynchrone code) een stuk simpeler maakt om te lezen, wel is het van belang wat fetch doet, oftewel een promise. Async/Await is een feature dat ES8 met zich meebracht om callbacks als het ware te versimpelen.
Vandaag waren we gaan onderzoeken hoe we de principes die we vorige week hebben geleerd te gebruiken bij een derde partij API. Bij het zoeken van de API had ik wel moeite met bedenken, de reden hiervoor was omdat we moeten kijken naar een API die kwantificeerbare informatie bevat om te visualiseren met D3.
Uiteindelijk ben ik op een API gekomen van the movie database die zich bezig houdt met informatie van films en series. Hier bedacht ik mij toen, ik kan de relatie tussen budget en score relativeren als dat een positieve of negatieve response zal creeeren.
Daarnaast bedacht ik ook dat ik op productie firma kan kwantificeren, welke firma maakt de best beoordeelde kaskrakers of juist de slechtste.
Vervolgens heb ik anderen geholpen met het probleem van node-fetch, dit is omdat node-fetch met import wilt werken en een nieuwere update van Node waardoor je node engine ook foutmeldingen geeft. IPV je package.json aan te passen om modules toe te laten kan je ook simpelweg de package cross-fetch gebruiken.
npm i cross-fetch
const fetch = require('cross-fetch')
fetch(URL)
.then(response => response.json())
.then(data => console.log(data))
// Expected outcome is an object of data
Later die dag heb ik een workshop gevolgd van Deanna Bosschert over het schrijven van documentatie, readme, en dergelijke. dit was waardevol in de zin van dat het helpt om te schrijven van wat je wilt in plaats van dat je achteraf schrijft. Hier had ik notities over geschreven in notion, eigenlijk een beetje meeschrijven.
Thuis ben ik nog verder aan de slag gegaan op een groot scherm, zo heb ik de utility functies opgesplitst in een eigen module en deze geimporteerd zodat de index.js opgeschoond is.
//72 regels code naar 8 regels code.
// index.js
const utilities = require('./modules/util')
//util.js
exports.getSpecificDataValue = getSpecificDataValue;
//... andere functies
Vervolgens heb ik nog gekeken naar linters en formatters. Zodat ik een specifieke stijl code heb en ervoor zorg dat ik minder errors en fouten maak tijdens het schrijven van code. De top 5 meest bekende linters zijn;
- eslint Pluggable linter die configurable is naar jouw wensen (of die van een bedrijf)
- prettier opinionated code formatter, formateert jouw codebase voor een consistente stijl.
- standard Standard een style guide, linter en formatter in één. heeft een eigen mening zonder dat je keuzes hoeft te maken.
- XO JS/TS linter (ESLint wrapper) met een eigen opinie. Geeft de gebruiker nog wel de keuze om het zelf te configureren.
- jshint Flexible JS linter alternative for JSLint (stricter)
Na het lezen van de documentatie en de keuze te hebben gemaakt dat ik zelf geen configuratie wil maken voor JS, kies ik voor Standard JS linting.
$ npm install standard --save-dev
# To use standard locally
$ npx standard
# Otherwise
$ standard
# After creating a script
$ npm run lint
Om het mijzelf hierna ook nog een stuk makkelijker te maken heb ik ook de VSCode plugin geinstalleerd. Alleen deze heb ik nog visueel niet werkend gekregen.
De dag begon met een ASYNC AWAIT les van Joost Faber, maar dit werd eerder een les over asynchronous code met XML requests, promises, callbacks en hoe dit op onderliggende niveau werkt. Dit werd in het nieuwe FDnD lokaal gegeven. Voor mij was dit een goeie refresher voor asynchronous code en gaf de motivatie om de promises te schrijven.
Deze promise heb ik uitgebreid om een verhaal te schrijven met de data die ik krijg van de dataset, deze data sla ik op in een persoon object waardoor ik dit makkelijker kan oproepen.
Tussendoor heb ik ook ontdekt waarom regelmatig de foutmelding TypeError: string.toLowerCase is not a function
krijg, dit heeft te maken dat mijn functie wel de string format wilt converteren maar doet dit niet meer wanneer een andere datatype langs komt. Dit heb ik opgelost door een typecheck uit te voeren.
const person = {
oogkleur: object['Wat is je oogkleur?'],
zuivel: object['Wat is je favoriete zuivelproduct?'],
wind: object['Wat is je favoriete windrichting?']
}
// Result
// { oogkleur: 'bruin', zuivel: 'melk', wind: 'oost' },
// { oogkleur: 'blauw', zuivel: 'kaas', wind: 'zuid' },
// { oogkleur: 'groen', zuivel: 'melk', wind: 'west' },
//...
/* Console.log()
persoon met oogkleur bruin vind zuivel product melk lekker in oost wind
persoon met oogkleur blauw vind zuivel product kaas lekker in zuid wind
persoon met oogkleur groen vind zuivel product melk lekker in west wind
*/
Met een bemachtigde API key ben ik mijn fetch poging modulair aan het maken. Omdat het een API is met een key heb ik eerst de package dotenv geinstalleerd, de reden hiervoor is omdat je sleutels veilig wilt stellen en niet delen met anderen. hiervoor gebruik je environment variabelen.
Belangrijk: vergeet niet je .env bestand in .gitignore te plaatsen
#Variable name and data
API_KEY=12345EENAPIKEYVALUESECRET
En het gebruik van de env variabelen:
require('dotenv').config()
console.log(process.env.API_KEY)
// returns 12345EENAPIKEYVALUESECRET
Vervolgens kan je dit dan gebruiken om data te fetchen van een API.
const getData = async (url) => {
return await fetch(url) // `https://www.api.com/3/something?apikey=${process.env.API_KEY`
.then(response => response.JSON()) //transforms and clean the response up so you see your requested data instead of API response
.then(data => console.log(data))
.catch(error => console.error(error))
}
//Returns a (or an array of) data object response(s)
{
adult: false,
backdrop_path: '/3nv2TEz2u178xPXzdKlZdUh5uOI.jpg',
belongs_to_collection: null,
budget: 63000000,
genres: [ { id: 18, name: 'Drama' } ],
homepage: 'http://www.foxmovies.com/movies/fight-club',
id: 550,
imdb_id: 'tt0137523',
original_language: 'en',
original_title: 'Fight Club',
overview: 'A ticking-time-bomb insomniac and a slippery soap salesman channel primal male aggression into a shocking new form of therapy. Their concept catches on, with underground "fight clubs" forming in every town, until an eccentric gets in the way and ignites an out-of-control spiral toward oblivion.',
popularity: 54.464,
poster_path: '/a26cQPRhJPX6GbWfQbvZdrrp9j9.jpg'
//...
}
Nu ik een enkele film terug kan krijgen kan ik gaan kijken naar data dat interessanter is, wellicht een array van data waar ik conclusies op kan loslaten. Hiervoor dacht ik aan een aantal films van een genre of de huidige die spelen. Ik heb de documentatie gelezen van TMDB en kwam erachter dat huidige listings het makkelijkst is ${url}/movie/now_playing
. Wel moet ik opletten dat ik nodemon niet laat draaien want anders ben ik wel erg snel door mijn amount of requests heen.
const getCurrentlyPlaying = () => {
utilities.getData(URL)
.then(data => {
console.log(data.results)
})
}
// RETURNS
[
{
adult: false,
backdrop_path: '/eENEf62tMXbhyVvdcXlnQz2wcuT.jpg',
genre_ids: [ 878, 28 ],
id: 580489,
original_language: 'en',
original_title: 'Venom: Let There Be Carnage',
overview: 'After finding a host body in investigative reporter Eddie Brock, the alien symbiote must face a new enemy, Carnage, the alter ego of serial killer Cletus Kasady.',
popularity: 6242.42,
poster_path: '/rjkmN1dniUHVYAtwuV3Tji7FsDO.jpg',
release_date: '2021-09-30',
title: 'Venom: Let There Be Carnage',
video: false,
vote_average: 6.9,
vote_count: 1412
},
// ...
Vandaag een beetje puntjes op de i plaatsen, ervoor zorgen dat ik redelijk content ben met wat ik heb geschreven en de wiki op orde heb staan. Zo ben ik voornamelijk mijn async/await
functies aan het herschrijven zodat het niet een mix is van promise chaining en async. Dit heb ik vervolgens ook met de getData()
functie gedaan zodat het er schoner uitziet.
From
const getData = async (URL) => {
return await fetch(URL)
.then(response => response.json())
.catch(error => console.error(error))
}
//https://github.com/bommezijn/functional-programming/commit/4841b292039085a24ac69a39c21f34c5623857c5#diff-fe04a32772b5159862985b3c8c4d211c6e5d76b21499d2647dbf8aad8c8308d9
To
const getData = async (URL) => {
try {
let response = await fetch(URL)
return response.json()
} catch (error) {
console.error(error)
}
}
// https://github.com/bommezijn/functional-programming/blob/d1ec73567484fc4e0ce4192e0a60585edfec5441/modules/util.js#L12-L19
Hierna zat ik te denken van is wat ik nu heb aan code wel voldoende dus ben naar Vincent gegaan om zijn advies te vragen hier kwam eigenlijk op neer dat het eigenlijk vooral belangrijk is dat je met verschillende type data hebt gewerkt. Dit klinkt nu ik het van een ander hoor eigenlijk vrijwel logisch.
Hierom besloot ik de date aan te passen indien deze in een amerikaanse formaat staat (dit gebeurt in mijn dataset). Mijn uiteindelijke solutie hiervoor zijn twee functies. één kijkt als het een geldige data formaat is, en de tweede manipuleert het naar een locale date formaat.
const isDate = (date) => {
return (new Date(date) !== "Invalid Date") && !isNaN(new Date(date));
}
/**
* @title Convert date format to local date format.
* @param {Date} date Date written in any manner, returns date in local date format.
* @returns {String} local date format in the datatype string
*/
const toLocalDateFormat = (date) => {
let checkDate = new Date(date)
return isDate(checkDate) ? checkDate.toLocaleDateString() : checkDate
}
/* Old vs new
https://github.com/bommezijn/functional-programming/commit/dab842012233495aa16ba52a4235116197b5d677
*/
Vervolgens heb ik ook een pagina geschreven over het opschonen van data. Deze kan je vinden in de wiki onder de pagina sanitize-data. Hier kan je eigenlijk de voornaamste functies vinden die de dataset opschonen naar een uniforme manier.
[
{
"date": "2021-10-25",
"title": "Start up",
"content": "it was fine, typical start up of a course in my opinion, we did some introductions and the way this 'seminar' is built up. We did some introductions within the support groups and had a bit of a chat up. Course wise I primarily did the setup for the subjects and started creating some functions for the data cleaning.",
"rating": 7
},
{
"date": "2021-10-26",
"title": "nvt",
"content": "Kiara uitgelegd hoe het zit met require paden en vervolgens een poging gedaan om verder te werken aan de functional programming patterns om de dataset op te schonen. Vandaag had ik moeite met het bedenken van logica omdat ik eigenlijk ieder object wil opschonen. Ik denk dat ik wellicht de theorie over de functional programming paradigm opnieuw moet doorlezen en een refresh course moet volgen.",
"rating": 7
}
]