Skip to content

Instantly share code, notes, and snippets.

@alekrutkowski
Last active September 23, 2025 08:17
Show Gist options
  • Save alekrutkowski/797ca03a87743ca6e25f5a27584f8b53 to your computer and use it in GitHub Desktop.
Save alekrutkowski/797ca03a87743ca6e25f5a27584f8b53 to your computer and use it in GitHub Desktop.
JavaScript function to fetch a CSV and put its rows into an array of objects, e.g. fetching data from Eurostat. Useful for feeding data into e.g. "Observable Framework" plots.
async function fetchCSVtoObjects(url) {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to fetch CSV: ${response.status} ${response.statusText}`);
}
const text = await response.text();
const lines = text.trim().split(/\r?\n/);
if (lines.length < 2) {
return [];
}
// Helper to split a CSV line while respecting quotes
function parseCSVLine(line) {
const result = [];
let current = '';
let insideQuotes = false;
for (let i = 0; i < line.length; i++) {
const char = line[i];
if (char === '"') {
if (insideQuotes && line[i + 1] === '"') {
// Escaped quote
current += '"';
i++;
} else {
// Toggle insideQuotes
insideQuotes = !insideQuotes;
}
} else if (char === ',' && !insideQuotes) {
result.push(current);
current = '';
} else {
current += char;
}
}
result.push(current);
return result.map(v => v.trim());
}
const headers = parseCSVLine(lines[0]);
const data = lines.slice(1).map(line => {
const values = parseCSVLine(line);
const row = {};
headers.forEach((header, i) => {
const value = values[i] ?? "";
const num = Number(value);
row[header] = (value !== "" && !isNaN(num)) ? num : value;
});
return row;
});
return data;
}
@alekrutkowski
Copy link
Author

Usage example:

// The URL is from https://ec.europa.eu/eurostat/databrowser/view/nama_10_gdp/default/table -> Make your selections -> Click [⤓] "Download" button -> Select: File format = "SDMX-CSV 2.0 (.csv)"; Data scope = Only displayed dimensions; Unticked = "Compress file (.gzip)" -> Click "Copy API link" button
const mydata = await fetchCSVtoObjects("https://ec.europa.eu/eurostat/api/dissemination/sdmx/3.0/data/dataflow/ESTAT/nama_10_gdp/1.0/*.*.*.*?c[freq]=A&c[unit]=CON_PPCH_PRE&c[na_item]=B1GQ&c[geo]=EU27_2020&c[TIME_PERIOD]=2015,2016,2017,2018,2019,2020,2021,2022,2023,2024&compress=false&format=csvdata&formatVersion=2.0&lang=en&labels=name");

console.log(mydata);
[
    {
        "STRUCTURE": "dataflow",
        "STRUCTURE_ID": "ESTAT:NAMA_10_GDP(1.0)",
        "STRUCTURE_NAME": "Gross domestic product (GDP) and main components (output, expenditure and income)",
        "freq": "A",
        "Time frequency": "Annual",
        "unit": "CON_PPCH_PRE",
        "Unit of measure": "Contribution to GDP growth, percentage point change on previous period",
        "na_item": "B1GQ",
        "National accounts indicator (ESA 2010)": "Gross domestic product at market prices",
        "geo": "EU27_2020",
        "Geopolitical entity (reporting)": "European Union - 27 countries (from 2020)",
        "TIME_PERIOD": 2015,
        "Time": "",
        "OBS_VALUE": 2.34,
        "Observation value": "",
        "OBS_FLAG": "",
        "Observation status (Flag) V2 structure": "",
        "CONF_STATUS": "",
        "Confidentiality status (flag)": ""
    },
    {
        "STRUCTURE": "dataflow",
        "STRUCTURE_ID": "ESTAT:NAMA_10_GDP(1.0)",
        "STRUCTURE_NAME": "Gross domestic product (GDP) and main components (output, expenditure and income)",
        "freq": "A",
        "Time frequency": "Annual",
        "unit": "CON_PPCH_PRE",
        "Unit of measure": "Contribution to GDP growth, percentage point change on previous period",
        "na_item": "B1GQ",
        "National accounts indicator (ESA 2010)": "Gross domestic product at market prices",
        "geo": "EU27_2020",
        "Geopolitical entity (reporting)": "European Union - 27 countries (from 2020)",
        "TIME_PERIOD": 2016,
        "Time": "",
        "OBS_VALUE": 1.92,
        "Observation value": "",
        "OBS_FLAG": "",
        "Observation status (Flag) V2 structure": "",
        "CONF_STATUS": "",
        "Confidentiality status (flag)": ""
    },
    {
        "STRUCTURE": "dataflow",
        "STRUCTURE_ID": "ESTAT:NAMA_10_GDP(1.0)",
        "STRUCTURE_NAME": "Gross domestic product (GDP) and main components (output, expenditure and income)",
        "freq": "A",
        "Time frequency": "Annual",
        "unit": "CON_PPCH_PRE",
        "Unit of measure": "Contribution to GDP growth, percentage point change on previous period",
        "na_item": "B1GQ",
        "National accounts indicator (ESA 2010)": "Gross domestic product at market prices",
        "geo": "EU27_2020",
        "Geopolitical entity (reporting)": "European Union - 27 countries (from 2020)",
        "TIME_PERIOD": 2017,
        "Time": "",
        "OBS_VALUE": 2.81,
        "Observation value": "",
        "OBS_FLAG": "",
        "Observation status (Flag) V2 structure": "",
        "CONF_STATUS": "",
        "Confidentiality status (flag)": ""
    },
    {
        "STRUCTURE": "dataflow",
        "STRUCTURE_ID": "ESTAT:NAMA_10_GDP(1.0)",
        "STRUCTURE_NAME": "Gross domestic product (GDP) and main components (output, expenditure and income)",
        "freq": "A",
        "Time frequency": "Annual",
        "unit": "CON_PPCH_PRE",
        "Unit of measure": "Contribution to GDP growth, percentage point change on previous period",
        "na_item": "B1GQ",
        "National accounts indicator (ESA 2010)": "Gross domestic product at market prices",
        "geo": "EU27_2020",
        "Geopolitical entity (reporting)": "European Union - 27 countries (from 2020)",
        "TIME_PERIOD": 2018,
        "Time": "",
        "OBS_VALUE": 2.06,
        "Observation value": "",
        "OBS_FLAG": "",
        "Observation status (Flag) V2 structure": "",
        "CONF_STATUS": "",
        "Confidentiality status (flag)": ""
    },
    {
        "STRUCTURE": "dataflow",
        "STRUCTURE_ID": "ESTAT:NAMA_10_GDP(1.0)",
        "STRUCTURE_NAME": "Gross domestic product (GDP) and main components (output, expenditure and income)",
        "freq": "A",
        "Time frequency": "Annual",
        "unit": "CON_PPCH_PRE",
        "Unit of measure": "Contribution to GDP growth, percentage point change on previous period",
        "na_item": "B1GQ",
        "National accounts indicator (ESA 2010)": "Gross domestic product at market prices",
        "geo": "EU27_2020",
        "Geopolitical entity (reporting)": "European Union - 27 countries (from 2020)",
        "TIME_PERIOD": 2019,
        "Time": "",
        "OBS_VALUE": 1.88,
        "Observation value": "",
        "OBS_FLAG": "",
        "Observation status (Flag) V2 structure": "",
        "CONF_STATUS": "",
        "Confidentiality status (flag)": ""
    },
    {
        "STRUCTURE": "dataflow",
        "STRUCTURE_ID": "ESTAT:NAMA_10_GDP(1.0)",
        "STRUCTURE_NAME": "Gross domestic product (GDP) and main components (output, expenditure and income)",
        "freq": "A",
        "Time frequency": "Annual",
        "unit": "CON_PPCH_PRE",
        "Unit of measure": "Contribution to GDP growth, percentage point change on previous period",
        "na_item": "B1GQ",
        "National accounts indicator (ESA 2010)": "Gross domestic product at market prices",
        "geo": "EU27_2020",
        "Geopolitical entity (reporting)": "European Union - 27 countries (from 2020)",
        "TIME_PERIOD": 2020,
        "Time": "",
        "OBS_VALUE": -5.56,
        "Observation value": "",
        "OBS_FLAG": "",
        "Observation status (Flag) V2 structure": "",
        "CONF_STATUS": "",
        "Confidentiality status (flag)": ""
    },
    {
        "STRUCTURE": "dataflow",
        "STRUCTURE_ID": "ESTAT:NAMA_10_GDP(1.0)",
        "STRUCTURE_NAME": "Gross domestic product (GDP) and main components (output, expenditure and income)",
        "freq": "A",
        "Time frequency": "Annual",
        "unit": "CON_PPCH_PRE",
        "Unit of measure": "Contribution to GDP growth, percentage point change on previous period",
        "na_item": "B1GQ",
        "National accounts indicator (ESA 2010)": "Gross domestic product at market prices",
        "geo": "EU27_2020",
        "Geopolitical entity (reporting)": "European Union - 27 countries (from 2020)",
        "TIME_PERIOD": 2021,
        "Time": "",
        "OBS_VALUE": 6.35,
        "Observation value": "",
        "OBS_FLAG": "",
        "Observation status (Flag) V2 structure": "",
        "CONF_STATUS": "",
        "Confidentiality status (flag)": ""
    },
    {
        "STRUCTURE": "dataflow",
        "STRUCTURE_ID": "ESTAT:NAMA_10_GDP(1.0)",
        "STRUCTURE_NAME": "Gross domestic product (GDP) and main components (output, expenditure and income)",
        "freq": "A",
        "Time frequency": "Annual",
        "unit": "CON_PPCH_PRE",
        "Unit of measure": "Contribution to GDP growth, percentage point change on previous period",
        "na_item": "B1GQ",
        "National accounts indicator (ESA 2010)": "Gross domestic product at market prices",
        "geo": "EU27_2020",
        "Geopolitical entity (reporting)": "European Union - 27 countries (from 2020)",
        "TIME_PERIOD": 2022,
        "Time": "",
        "OBS_VALUE": 3.54,
        "Observation value": "",
        "OBS_FLAG": "",
        "Observation status (Flag) V2 structure": "",
        "CONF_STATUS": "",
        "Confidentiality status (flag)": ""
    },
    {
        "STRUCTURE": "dataflow",
        "STRUCTURE_ID": "ESTAT:NAMA_10_GDP(1.0)",
        "STRUCTURE_NAME": "Gross domestic product (GDP) and main components (output, expenditure and income)",
        "freq": "A",
        "Time frequency": "Annual",
        "unit": "CON_PPCH_PRE",
        "Unit of measure": "Contribution to GDP growth, percentage point change on previous period",
        "na_item": "B1GQ",
        "National accounts indicator (ESA 2010)": "Gross domestic product at market prices",
        "geo": "EU27_2020",
        "Geopolitical entity (reporting)": "European Union - 27 countries (from 2020)",
        "TIME_PERIOD": 2023,
        "Time": "",
        "OBS_VALUE": 0.41,
        "Observation value": "",
        "OBS_FLAG": "",
        "Observation status (Flag) V2 structure": "",
        "CONF_STATUS": "",
        "Confidentiality status (flag)": ""
    },
    {
        "STRUCTURE": "dataflow",
        "STRUCTURE_ID": "ESTAT:NAMA_10_GDP(1.0)",
        "STRUCTURE_NAME": "Gross domestic product (GDP) and main components (output, expenditure and income)",
        "freq": "A",
        "Time frequency": "Annual",
        "unit": "CON_PPCH_PRE",
        "Unit of measure": "Contribution to GDP growth, percentage point change on previous period",
        "na_item": "B1GQ",
        "National accounts indicator (ESA 2010)": "Gross domestic product at market prices",
        "geo": "EU27_2020",
        "Geopolitical entity (reporting)": "European Union - 27 countries (from 2020)",
        "TIME_PERIOD": 2024,
        "Time": "",
        "OBS_VALUE": 1.01,
        "Observation value": "",
        "OBS_FLAG": "",
        "Observation status (Flag) V2 structure": "",
        "CONF_STATUS": "",
        "Confidentiality status (flag)": ""
    }
]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment