Skip to content

Instantly share code, notes, and snippets.

@badosa
Last active May 17, 2020 08:41
Show Gist options
  • Save badosa/f13847d3e99ebecc69caf03c713bd2a6 to your computer and use it in GitHub Desktop.
Save badosa/f13847d3e99ebecc69caf03c713bd2a6 to your computer and use it in GitHub Desktop.
Unemployment rate according to several sources

This is an example of simultaneously fetching data from several JSON-stat compatible APIs using async/await and displaying each datum as soon as it is available.

For a similar example where the table is only filled once all the data have been fetched, see Unemployment in Norway according to different sources.

<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="UTF-8">
<title>Unemployment rate</title>
<link href="https://fonts.googleapis.com/css?family=Montserrat|Montserrat:700&display=swap" rel="stylesheet" />
<link href="/d/8e7f41e61eb9576ea016e8c624d81400/styles.css" rel="stylesheet" type="text/css" />
<script src="https://cdn.jsdelivr.net/combine/npm/jsonstat@0.13.13,npm/jsonstat-utils@2.5.5"></script>
</head>
<body>
<main></main>
<script>
const sources=[
{
id: "no",
label: "Norway", //table label
geo: null, //No need to filter the data for a geo
countries: [ { id: "no" } ], //ssb.no provides data for NO
process: null, //No need to post-process the data
method: "post",
url: "https://data.ssb.no/api/v0/en/table/08517",
data: {
"query": [
{
"code": "ContentsCode",
"selection": {
"filter": "item",
"values": [
"Prosent"
]
}
},
{
"code": "Tid",
"selection": {
"filter": "top",
"values": [
"5"
]
}
}
],
"response": {
"format": "json-stat2"
}
}
},
{
id: "dk",
label: "Denmark",
geo: null,
countries: [ { id: "dk" } ],
process: null,
method: "get",
url: "https://api.statbank.dk/v1/data/AKU121/JSONSTAT?lang=en&BESKSTATUS=LPCT&ALDER=TOT&K%C3%98N=TOT&Tid=*"
},
{
id: "fi",
label: "Finland",
geo: null,
countries: [ { id: "fi" } ],
process: null,
method: "post",
url: "https://pxnet2.stat.fi/PXWeb/api/v1/en/StatFin/tym/tyti/vv/statfin_tyti_pxt_11pl.px",
data: {
"query": [
{
"code": "Vuosi",
"selection": {
"filter": "top",
"values": ["5"]
}
},
{
"code": "Sukupuoli",
"selection": {
"filter": "item",
"values": [
"SSS"
]
}
},
{
"code": "Ikäluokka",
"selection": {
"filter": "item",
"values": [
"15-74"
]
}
},
{
"code": "Tiedot",
"selection": {
"filter": "item",
"values": [
"Tyottomyysaste"
]
}
}
],
"response": {
"format": "json-stat"
}
}
},
/* Italy was the first country to support JSON-STAT. Unfortunately, it does not support JSON-stat anymore
{
id: "it",
label: "Italy",
time: "IDTIME", //No time role available
geo: null,
countries: [ { id: "it" } ],
process: (ds, f)=>ds.toTable({type: "arrobj"}, e=>{ if(e["IDTIME"].length===4) { return e[f]; } }),
method: "get",
url: "http://apistat.istat.it/?q=getdatajson&dataset=DCCV_TAXDISOCCU1&dim=1,6,3,26,12,7,16,0&lang=1"
},
*/
{
id: "eurostat",
label: null, //not a table
time: "time", //No time role available
geo: "geo",
countries: [
{ id: "no", value: "NO" },
{ id: "dk", value: "DK" },
{ id: "fi", value: "FI" }
/* Italy is gone: { id: "it", value: "IT" }*/
],
method: "get",
url: "https://ec.europa.eu/eurostat/wdds/rest/data/v2.1/json/en/une_rt_a?sinceTimePeriod=2000&precision=1&sex=T&geo=NO&geo=DK&geo=FI&unit=PC_ACT&age=Y15-74"
},
{
id: "oecd",
label: null, //not a table
geo: "COUNTRY",
countries: [
{ id: "no", value: "NOR" },
{ id: "dk", value: "DNK" },
{ id: "fi", value: "FIN" }
/* Italy is gone { id: "it", value: "ITA" } */
],
process: null,
method: "get",
url: "https://stats.oecd.org/SDMX-JSON/data/LFS_SEXAGE_I_R/DNK+FIN+NOR.MW.900000.UR.A/all?startTime=2010&dimensionAtObservation=allDimensions"
},
{
id: "unece",
label: null, //not a table
time: "Year", //No time role available
geo: "Country",
countries: [
{ id: "no", value: "578" },
{ id: "dk", value: "208" },
{ id: "fi", value: "246" }
/* Italy is gone { id: "it", value: "380" } */
],
process: null,
method: "post",
url: "https://w3.unece.org/PXWeb2015/api/v1/en/STAT/20-ME/3-MELF/40_en_MEUnRateY_r.px",
data: {
"query": [
{
"code": "Country",
"selection": {
"filter": "item",
"values": [
"208", //DK
"246", //FI
// Italy is gone "380", //IT
"578" //NO
]
}
}/*, There seems to be a problem with UNECE's API: wrong support of PC-Axis "top"
{
"code": "Year",
"selection": {
"filter": "top",
"values": ["5"]
}
}*/
],
"response": {
"format": "json-stat"
}
}
}
];
//Build table
let html="";
sources.forEach(async (e)=>{
if(e.label){
html+=`<table id="${e.id}"><caption>Unemployment rate in ${e.label}</caption><colgroup><col /><col span="2" /><col span="2" /><col span="2" /><col span="2" /></colgroup><thead><tr><th class="void" rowspan="2"></th><th colspan="2">Last period</th><th colspan="2">Last period &minus; 1</th><th colspan="2">Last period &minus; 2</th><th colspan="2">Last period &minus; 3</th></tr><tr><th class="time">Year</th><th class="value">Value</th><th class="time">Year</th><th class="value">Value</th><th class="time">Year</th><th class="value">Value</th><th class="time">Year</th><th class="value">Value</th></tr></thead><tbody><tr class="${e.id}"><th>NSO</th><td class="t0 time"></td><td class="t0 value"></td><td class="t1 time"></td><td class="t1 value"></td><td class="t2 time"></td><td class="t2 value"></td><td class="t3 time"></td><td class="t3 value"></td></tr><tr class="eurostat"><th>Eurostat</th><td class="t0 time"></td><td class="t0 value"></td><td class="t1 time"></td><td class="t1 value"></td><td class="t2 time"></td><td class="t2 value"></td><td class="t3 time"></td><td class="t3 value"></td></tr><tr class="oecd"><th>OECD</th><td class="t0 time"></td><td class="t0 value"></td><td class="t1 time"></td><td class="t1 value"></td><td class="t2 time"></td><td class="t2 value"></td><td class="t3 time"></td><td class="t3 value"></td></tr><tr class="unece"><th>UNECE</th><td class="t0 time"></td><td class="t0 value"></td><td class="t1 time"></td><td class="t1 value"></td><td class="t2 time"></td><td class="t2 value"></td><td class="t3 time"></td><td class="t3 value"></td></tr></tbody></table>`;
}
});
document.querySelector("main").innerHTML=html;
sources.forEach(async (e,i)=>{
const options={ method: e.method };
if(e.method==="post"){
options["body"]=JSON.stringify(e.data);
}
const
res=await fetch(e.url, options),
json=await res.json(),
ds=JSONstat( json.structure ? JSONstatUtils.fromSDMX(json) : json).Dataset(0),
source=sources[i],
id=source.id,
countries=source.countries,
time=ds.Dimension( ds.role && ds.role.time ? ds.role.time[0] : source.time )
;
countries.forEach(country=>{
const
filter=source.geo ? [[source.geo, country.value]] : {},
value=(source.process) ? source.process(ds, "value") : ds.Data(filter, false),
last=value.length-1,
idclass="#"+country.id+" ."+id+" .t"
;
for(let j=0; j<4; j++){
document.querySelector(idclass+j+".time").innerText=(source.process) ? source.process(ds, source.time)[last-j] : time.Category(last-j).label;
document.querySelector(idclass+j+".value").innerText=(value[last-j]) ? value[last-j].toFixed(1)+" %" : "—";
}
});
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment