Skip to content

Commit

Permalink
Timeout fetch
Browse files Browse the repository at this point in the history
  • Loading branch information
slowe committed Oct 15, 2024
1 parent 6cef74a commit 2ce2002
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 77 deletions.
40 changes: 22 additions & 18 deletions 2024-DFES/resources/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,27 +224,31 @@ OI.ready(function(){
if(url.match("https://northernpowergrid.opendatasoft.com/api/explore/v2.1/")){
var rows = d.replace(/[\n\r]+$/,'').split(/\r\n/);
var r,cols,c,head = {},header = [],orows = new Array(rows.length-1);
for(r = 0; r < rows.length; r++){
cols = rows[r].split(/\;/);
if(r==0){
header = [data.key];
for(c = 0; c < cols.length; c++){
head[cols[c]] = c;
if(cols[c]==parseInt(cols[c])) header.push(parseInt(cols[c]));
}
}else{
orows[r-1] = new Array(header.length);
for(c = 0; c < header.length; c++){
id = header[c];
if(id==data.key){
v = cols[head[id]].toUpperCase();
}else{
v = cols[head[id]];
if(parseFloat(v)==v) v = parseFloat(v);
if(rows.length > 1){
for(r = 0; r < rows.length; r++){
cols = rows[r].split(/\;/);
if(r==0){
header = [data.key];
for(c = 0; c < cols.length; c++){
head[cols[c]] = c;
if(cols[c]==parseInt(cols[c])) header.push(parseInt(cols[c]));
}
}else{
orows[r-1] = new Array(header.length);
for(c = 0; c < header.length; c++){
id = header[c];
if(id==data.key){
v = cols[head[id]].toUpperCase();
}else{
v = cols[head[id]];
if(parseFloat(v)==v) v = parseFloat(v);
}
orows[r-1][c] = v;
}
orows[r-1][c] = v;
}
}
}else{
this.message('No data loaded from API',{'id':'error','type':'ERROR'});
}
// We need to add a "raw" variable that consists of { header: [], rows: [] }
data.raw = {'rows':orows,'header':header};
Expand Down
125 changes: 71 additions & 54 deletions 2024-DFES/resources/dfes.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,35 +80,34 @@
if(!this.options.files.parameters) this.options.files.parameters = path+"data/scenarios/config.json";
if(!this.options.files.scenarios) this.options.files.scenarios = path+"data/scenarios/index.json";

fetch(this.options.files.parameters,{}).then(response => {
if(!response.ok) throw new Error('Network response was not OK');
return response.json();
}).then(d => {
if(d.length){
this.parameters = {};
// New style (1.5.0) config is an array to preserve order - convert into object
for(var i = 0; i < d.length; i++){
if(d[i].key) this.parameters[d[i].key] = d[i];
}
}else this.parameters = d;
fetch(this.options.files.scenarios,{}).then(response => {
if(!response.ok) throw new Error('Network response was not OK');
return response.json();
}).then(d => {
this.log('MSG','Got '+this.options.files.scenarios);
this.fetch(this.options.files.parameters,{
'type':'json',
'callback': function(d){
if(d.length){
this.data.scenarios = {};
this.parameters = {};
// New style (1.5.0) config is an array to preserve order - convert into object
for(var i = 0; i < d.length; i++){
if(d[i].key) this.data.scenarios[d[i].key] = d[i];
if(d[i].key) this.parameters[d[i].key] = d[i];
}
}else this.data.scenarios = d;
this.init();
}).catch(e => {
this.message('Unable to load scenarios from '+this.options.files.scenarios.replace(/\?.*/,""),{'id':'error','type':'ERROR'});
});
}).catch(e => {
this.message('Unable to load parameters from '+this.options.files.parameters.replace(/\?.*/,""),{'id':'error','type':'ERROR'})
}else this.parameters = d;

this.fetch(this.options.files.scenarios,{
'type':'json',
'callback': function(d){
this.log('MSG','Got '+this.options.files.scenarios);
if(d.length){
this.data.scenarios = {};
// New style (1.5.0) config is an array to preserve order - convert into object
for(var i = 0; i < d.length; i++){
if(d[i].key) this.data.scenarios[d[i].key] = d[i];
}
}else this.data.scenarios = d;
this.init();
},
'error':'Unable to load scenarios from '
});
},
'error': 'Unable to load parameters from '
});

return this;
Expand Down Expand Up @@ -270,14 +269,13 @@
var url = this.data.scenarios[this.options.scenario].data[this.options.parameter].file;
if(!url.match(/^https/)) url = path+"data/scenarios/"+this.data.scenarios[this.options.scenario].data[this.options.parameter].file;
this.log('INFO','Getting data from %c'+url.replace(/\%/g,'\\%')+'%c','font-style:italic;','')
fetch(url,{}).then(response => {
if(!response.ok) throw new Error('Network response was not OK');
return response.text();
}).then(d => {
this.log('MSG','Got '+url);
this.loadedData(d,this.options.scenario,this.options.parameter,callback,url);
}).catch(e => {
this.message('Unable to load data from '+url.replace(/\?.*/,""),{'id':'error','type':'ERROR'});
this.fetch(url,{
'type':'text',
'callback': function(d){
this.log('MSG','Got '+url);
this.loadedData(d,this.options.scenario,this.options.parameter,callback,url);
},
'error':'Unable to load data from '
});
};

Expand Down Expand Up @@ -491,17 +489,16 @@
if(!this.mapping[data.dataBy][id].data && typeof this.mapping[data.dataBy][id].file==="string"){
// Load from JSON file
var url = path+this.mapping[data.dataBy][id].file;
fetch(url,{}).then(response => {
if(!response.ok) throw new Error('Network response was not OK');
return response.json();
}).then(d => {
this.log('MSG','Got '+url);
this.mapping[data.dataBy][id].raw = d;
if(typeof this.mapping[data.dataBy][id].process==="function") d = this.mapping[data.dataBy][id].process.call(this,d);
this.mapping[data.dataBy][id].data = d;
this.mapData();
}).catch(e => {
this.message('Unable to load '+url.replace(/\?.*/,""),{'id':'error','type':'ERROR'});
this.fetch(url,{
'type':'json',
'callback': function(d){
this.log('MSG','Got '+url);
this.mapping[data.dataBy][id].raw = d;
if(typeof this.mapping[data.dataBy][id].process==="function") d = this.mapping[data.dataBy][id].process.call(this,d);
this.mapping[data.dataBy][id].data = d;
this.mapData();
},
'error': 'Unable to load '
});

return this;
Expand Down Expand Up @@ -774,15 +771,14 @@
document.querySelector('#map .spinner').style.display = '';
var url = path+this.layers[layer.id].geojson;

fetch(url,{}).then(response => {
if(!response.ok) throw new Error('Network response was not OK');
return response.json();
}).then(d => {
this.log('MSG','Got '+url);
this.layers[layer.id].geojson = d;
this.buildMap();
}).catch(e => {
this.message('Unable to load GeoJSON '+url.replace(/\?.*/,""),{'id':'error','type':'ERROR'});
this.fetch(url,{
'type':'json',
'callback':function(d){
this.log('MSG','Got '+url);
this.layers[layer.id].geojson = d;
this.buildMap();
},
'error':'Unable to load GeoJSON '
});
return this;
}
Expand Down Expand Up @@ -953,6 +949,27 @@
return this;
};

FES.prototype.fetch = function(resource, options = {}) {
var { timeout = 3000 } = options;
var controller = new AbortController();
var id = setTimeout(() => controller.abort(), timeout);
this.log('INFO','Get '+resource);
var response = fetch(resource,{
...options,
signal: controller.signal
}).then(response=>{
if(!response.ok) throw new Error('Network response was not OK');
if(options.type=="json") return response.json();
else return response.text();
}).then(d=>{
if(typeof options.callback==="function") options.callback.call(this,d);
}).catch(e => {
this.message((options.error ? options.error : 'Unable to load from ')+resource.replace(/\?.*/,""),{'id':'error','type':'ERROR'})
});
clearTimeout(id);
return this;
}

function popuptext(feature,attr){
// does this feature have a property named popupContent?
var popup,me,view,key,v,lid;
Expand Down Expand Up @@ -1424,4 +1441,4 @@ function appendHTML(el,html){
else el.append(html);
}
return el;
}
}
8 changes: 3 additions & 5 deletions 2024-DFES/resources/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,9 @@


.message { text-align: center; }
.warning {
color: rgb(95, 82, 7);
background-color: rgb(251, 245, 208);
filter: drop-shadow(0px 0px 1px rgb(95, 82, 7));
}
.warning { color: rgb(95, 82, 7); background-color: rgb(251, 245, 208); filter: drop-shadow(0px 0px 1px rgb(95, 82, 7)); }
.error { color: #721c24; background-color: #f8d7da; filter: drop-shadow(0 0 1px #f5c6cb)); }

.holder > *:last-child { margin-bottom: 0; }

ol { list-style: decimal; margin-left: 2em; margin-bottom: 1em; }
Expand Down

0 comments on commit 2ce2002

Please sign in to comment.