Survey Exercise - GiovanniDw/functional-programming GitHub Wiki
The Survey Exercise
Before we started using the data from the opendata.rdw.nl, we had to do an exercise to process the data from the survey
Table of Contents
About the exercise
For this exersize we had to clean our own survey data. This data was collected at the start of the course, and was stored in a CSV file. This CSV file was cleaned and parsed into a JSON file by Jonah, Thanks for sharing!
Getting the Data
In my first attempt to log the data to the console, I tried to open the local folder in the browser and used the fetch()
API method.
First attempt
fetch('../data/survey_id.json')
.then((response) => {
return response.json();
})
.then((obj) => {
console.log(obj);
})
.catch((error) => {
console.error('nope');
});
This is the result i got from the console:
Cross origin requests are only supported for HTTP.
___
[Error] Fetch API cannot load [filepath] due to access control checks.
To fix this error I used the package live-server
.
For easy use I've added live-server
to my start script.
The server will start by running the command: $ npm start
in the terminal.
The JSON data is now logged to the console.
Next Step
For better readability of the code i rewrote the code adding some callbacks
const data = '../data/survey_id.json';
getData = (data) => {
fetch(data)
.then(status)
.then(json)
.then((data) => {
console.log('Request succeeded with JSON response', data);
})
.catch((error) => {
console.error('nope' + error);
});
};
getData(data);
Get the response status
status = (response) => {
if (response.status >= 200 && response.status < 300) {
console.log(response);
return Promise.resolve(response);
} else {
return Promise.reject(new Error(response.statusText));
}
};
Read the JSON response
json = (response) => {
return response.json();
};
Improvements
I've rewrote some functions to improve reusability.
And changed function names to match the functionality.
const data = '../data/Survey_Information_Design_clean-parsed.json';
fetchJSON = (data) => {
fetch(data)
.then(responseStatus)
.then(readResponseJSON)
.then(logResult)
.catch((error) => {
console.error('nope' + error);
});
};
Get Response Status
responseStatus = (response) => {
if (response.status >= 200 && response.status < 300) {
console.log(response);
return Promise.resolve(response);
} else {
return Promise.reject(new Error(response.statusText));
}
};
Read the response
readResponseJSON = (response) => {
return response.json();
};
log the results to the console.
logResult = (result) => {
console.log(result);
};
Final version
Filter The Data
Get data by column name
To filter the data and find answers by column name i wrote this function.
function getAnswersByColName(results, colName) {
if (results.length < 1) {
console.log('No Items in result');
return;
}
let resultByColName = [];
for (result of results) {
resultByColName.push(result[colName]);
}
return resultByColName;
};
Clean the Data
Cleaning Dates
Date Strings:
"geboortedatum"
&"tijdreisJaar"
When I tried to calculate the age from a birthday string
I found out that javascript couldn't read the dd-mm-yyyy
date format.
Birthdates
To read these dates correctly the format had to be changed this function was my attempt to fix the problem:
convertDateString = (date) => {
let convertedDates = [];
date.forEach(dateString => {
let dateParts = dateString.split('-');
let dateObj = new Date(+dateParts[2], dateParts[1] - 1, +dateParts[0]);
convertedDates.push(dateObj.toString())
});
return convertedDates
}
Input: "13-01-1994"
Output: Thu Jan 13 1994 00:00:00 GMT+0100 (CET)
The birthday dates where pretty clean compared to the timetracel dates. The timetravel dates where formatted even worse.
Time Travel Dates
function transformDates(results) {
console.log('Transform date function');
let getDates = getAnswersByColName(results, 'tijdreisJaar');
console.log(getDates);
let newDates = formatDateString(getDates);
console.log(newDates);
return results;
};
function formatDateString(date) {
let convertedDates = [];
date.forEach((dateString) => {
if (dateString) {
let dateParts = dateString
.replaceAll('-', '/')
.split('/');
let dateObj = new Date(
+dateParts[2],
dateParts[1] - 1,
+dateParts[0]
);
convertedDates.push(dateObj.toString());
}
});
console.log(convertedDates);
return convertedDates;
};
Cleaning Dates Improvements
Updates might follow
Manipulate The Data
Calculate Siblings
I tried to calculate the amount of siblings an object has by combining the amount of brothers & sisters.
calcSiblings = (result) => {
let siblings = [];
for (let i = 0; i < result.length; i++) {
let getBrothers = result[i].hoeveelheidBroers;
let getSisters = result[i].hoeveelheidZussen;
siblings.push(getBrothers + getSisters);
}
console.log(siblings);
return;
};
The output of this method wasn't correct because 2 strings of numbers being added together.
Example:
"2" + "1" = "21"
To Fix this problem I had to write a function to convert number properties inside a string to a number property.
stringToNumber = (results) => {
console.log('str to nm');
console.log(results);
for (let i = 0; i < results.length; i++) {
let obj = results[i];
for (let prop in obj) {
if (obj.hasOwnProperty(prop) && !isNaN(obj[prop])) {
obj[prop] = +obj[prop];
}
}
}
return results;
};