Skip to content

Verzamelen data

ralfz123 edited this page Jan 27, 2021 · 3 revisions

Inhoud


Receive data (fetch)

Allereerst om data van een API te 'fetchen', kan ik een promise gebruiken, omdat je met de fetch() methode ook een promise terugkrijgt. Ik handel dit dan af met een .then en .catch. Dit is een vorm van asynchronous programming.

Code
const endpointOne = 'https://opendata.rdw.nl/resource/b3us-f26s.json'; // API endpoint - Charging Points (dataset 1)

fetch(endpointOne)
    .then(res => res.json()) // Translates to JSON format
    .then(data => console.log("Data is:", data)) // Logging the retrieved data
    .catch(error => console.log('ERROR')) // Catches and shows an error when it's occurring

Maar om asynchronous programming toe te passen, wat eigenlijk wel hoort bij de fetch() methode, zal ik gebruik moeten maken van async await. Hierbij start een functie terwijl een andere functie nog bezig is. Er komt zoals Danny zou zeggen 'Syntax Sugar' bovenop de promises.

Code
const endpointOne = 'https://opendata.rdw.nl/resource/b3us-f26s.json'; // API endpoint - Charging Points (dataset 1)
const selectedColumn = 'areaid';

// Fetching data - API
fetchingData(endpointOne)
  .then((dataRDW) => {
          console.log(dataRDW) 
  })

// Receiving data using fetch()
async function fetchingData(url) {
  try {
    const response = await fetch(url); // Waits till the data is fetched
    const data = await response.json(); // Waits till the data is formatted to JSON
    return data; // Returns the JSON data
  } catch {
    console.log(err); // Catches and shows an error when it's occurring
  }
}

Ik vind deze code wel veel gemakkelijker (lezen) en het is overzichtelijker, omdat de functie nu uit elkaar is gehaald en in meerdere functies is opgeschreven. Daarom heb ik de fetchingData function in async geschreven. Je kan er natuurlijk voor kiezen om geen async await te gebruiken, omdat dit niet de enige manier is, maar het is wel een manier waardoor je code overzichtelijker wordt en begrijpbaarder voor andere developers.

Filter data

De .map() methode maakt een nieuw array aan met een unieke key. De key wordt meegegeven als tweede parameter aan de functie. Hij returnt de waarden in de console.log.

Code
// Fetching data - API
fetchingData(endpointOne)
  .then((dataRDW) => {
    const getAreaIdArray = newDataArray(dataRDW, selectedColumn);
    const getCapacityArray = newDataArray(dataRDW, 'capacity');
    console.log("AreaId is:", getAreaIdArray);
    console.log("Charging Capacity is:", getCapacityArray);
  })

// Receiving data using fetch()
async function fetchingData(url) {
  try {
    const response = await fetch(url); // Waits till the data is fetched
    const data = await response.json(); // Waits till the data is formatted to JSON
    return data; // Returns the JSON data
  } catch {
    console.log(err); // Catches and shows an error when it's occurring
  }
}

// Filter data - Make a new Array based on an unique key
function newDataArray(dataArray, key) { 
  return dataArray.map((item) => item[key]);
}

Ik heb nu een stukje code geschreven, samen met Sam de Kanter (shoutout to you!), waardoor alle items per object van een unieke key (variabele) naar nummer (Number()) worden getransformeerd. Hierbij wordt ook gekeken of de waarden niet gelijk aan of onder de 0 zijn, anders worden deze waarden 'undefined'. De reden hiervoor, is omdat het bij deze functie vooral gaat over de capaciteit van een parkeergebied. Die kan niet gelijk aan 0 zijn en al helemaal niet negatief. Daarom heb ik ervoor gekozen dat deze waarden getransformeerd worden naar null.

Code
// Filter and transform data - Make a new Array based on an unique key and checks if value is correct
function newDataArray(dataArray, key) {
   return dataArray.map((item) => {
	item[key] = Number(item[key]); // Makes all items from unique key a NUMBER type.

	if (item[key] <= 0) { // When item is lower than or equal to 0, return null
		console.log('Negative or zero value');
		return null;
	} else {
		return item[key];
	}
});
}

Promise.all()

Ik heb de bovenste code niet meer gebruikt, omdat het uiteindelijk niet lekker aansloot bij mijn casus. Ik wilde namelijk 2 datasets fetchen, en die samen mergen in 1 array. Ik heb hiervoor de methode Promise.all() gebruikt, omdat deze methode een aantal promises als input neemt en 1 single promise returnt.

Code
const endpointOne = 'https://raw.githubusercontent.com/ralfz123/frontend-data/main/d3/data/dataDay.json'; // Data from a Day - 08:00h
const endpointTwo = 'https://raw.githubusercontent.com/ralfz123/frontend-data/main/d3/data/dataEve.json'; // Data from a Eve - 20:00h

// Fetching data
// Receiving data using fetch()
const dataDay = fetch(endpointOne).then((response) => response.json()); // Parses JSON data
const dataEve = fetch(endpointTwo).then((response) => response.json()); // Parses JSON data

// Getting both datasets through an Promise.all (is solved when all promises above get resolved)
Promise.all([dataDay, dataEve]).then((response) => {
	let [dataset1, dataset2] = response;
	filteredDataset(dataset1, dataset2);
});

// Clean data - makes new array with needed data variables
function filteredDataset(dataDay, dataEve) {
	const cleanDataDay = dataDay.map((element) => {
		const object = {};
		object.point = element.point;
		object.status = element.status;

		return object;
	});

	const cleanDataEve = dataEve.map((element) => {
		const object = {};
		object.point = element.point;
		object.status = element.status;

		return object;
	});

	const combinedData = [cleanDataDay, cleanDataEve]; 
Verschil Async Await vs Promise.all() bij fetching

Async await kan geen 6 calls. Syntax Sugar bovenop promises.
Promise.all() kan beter omgaan met error handling, geeft allemaal in 1 keer de error ipv async await dat doet. Bij async await namelijk weet je nooit welke promise een error heeft gegeven.

Clone this wiki locally