remove additional jquery ajax requests

This commit is contained in:
Matt Walsh 2020-10-01 21:35:49 -05:00
parent 5a766a809d
commit 456af1b09a
11 changed files with 86 additions and 124 deletions

View file

@ -1,5 +1,5 @@
'use strict'; 'use strict';
/* globals NoSleep, states, navigation, UNITS */ /* globals NoSleep, states, navigation, UNITS, utils */
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
index.init(); index.init();
}); });
@ -170,35 +170,27 @@ const index = (() => {
postMessage('units', Units); postMessage('units', Units);
}; };
const autocompleteOnSelect = (suggestion) => { const autocompleteOnSelect = async (suggestion) => {
let request;
// Do not auto get the same city twice. // Do not auto get the same city twice.
if (this.previousSuggestionValue === suggestion.value) return; if (this.previousSuggestionValue === suggestion.value) return;
if (overrides[suggestion.value]) { if (overrides[suggestion.value]) {
doRedirectToGeometry(overrides[suggestion.value]); doRedirectToGeometry(overrides[suggestion.value]);
} else { } else {
request = $.ajax({ const data = await utils.fetch.json('https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find', {
<<<<<<< Updated upstream
url: 'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find',
=======
url: location.protocol + 'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find',
>>>>>>> Stashed changes
data: { data: {
text: suggestion.value, text: suggestion.value,
magicKey: suggestion.data, magicKey: suggestion.data,
f: 'json', f: 'json',
}, },
}); });
request.done((data) => {
const loc = data.locations[0]; const loc = data.locations[0];
if (loc) { if (loc) {
doRedirectToGeometry(loc.feature.geometry); doRedirectToGeometry(loc.feature.geometry);
} else { } else {
alert('An unexpected error occurred. Please try a different search string.'); alert('An unexpected error occurred. Please try a different search string.');
} }
});
} }
}; };
@ -501,8 +493,7 @@ const index = (() => {
let data; let data;
try { try {
data = await $.ajax({ data = await utils.fetch.json(location.protocol + '//geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode', {
url: location.protocol + '//geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode',
data: { data: {
location: longitude + ',' + latitude, location: longitude + ',' + latitude,
distance: 1000, // Find location up to 1 KM. distance: 1000, // Find location up to 1 KM.

View file

@ -17,22 +17,14 @@ class CurrentWeather extends WeatherDisplay {
let observations, station; let observations, station;
try { try {
// station observations // station observations
const observationsPromise = $.ajaxCORS({ const observationsPromise = utils.fetch.json(`https://api.weather.gov/stations/${weatherParameters.stationId}/observations`,{
type: 'GET', cors: true,
url: `https://api.weather.gov/stations/${weatherParameters.stationId}/observations`,
data: { data: {
limit: 2, limit: 2,
}, },
dataType: 'json',
crossDomain: true,
}); });
// station info // station info
const stationPromise = $.ajax({ const stationPromise = utils.fetch.json(`https://api.weather.gov/stations/${weatherParameters.stationId}`);
type: 'GET',
url: `https://api.weather.gov/stations/${weatherParameters.stationId}`,
dataType: 'json',
crossDomain: true,
});
// wait for the promises to resolve // wait for the promises to resolve
[observations, station] = await Promise.all([observationsPromise, stationPromise]); [observations, station] = await Promise.all([observationsPromise, stationPromise]);
@ -40,7 +32,7 @@ class CurrentWeather extends WeatherDisplay {
// TODO: add retry for further stations if observations are unavailable // TODO: add retry for further stations if observations are unavailable
} catch (e) { } catch (e) {
console.error('Unable to get current observations'); console.error('Unable to get current observations');
console.error(e.status, e.responseJSON); console.error(e);
this.setStatus(STATUS.failed); this.setStatus(STATUS.failed);
return; return;
} }

View file

@ -25,14 +25,10 @@ class ExtendedForecast extends WeatherDisplay {
if (navigation.units() === UNITS.metric) units = 'si'; if (navigation.units() === UNITS.metric) units = 'si';
let forecast; let forecast;
try { try {
forecast = await $.ajax({ forecast = await utils.fetch.json(weatherParameters.forecast,{
type: 'GET',
url: weatherParameters.forecast,
data: { data: {
units, units,
}, },
dataType: 'json',
crossDomain: true,
}); });
} catch (e) { } catch (e) {
console.error('Unable to get extended forecast'); console.error('Unable to get extended forecast');

View file

@ -31,12 +31,7 @@ class LatestObservations extends WeatherDisplay {
// get data for regional stations // get data for regional stations
const allConditions = await Promise.all(regionalStations.map(async station => { const allConditions = await Promise.all(regionalStations.map(async station => {
try { try {
const data = await $.ajax({ const data = await utils.fetch.json(`https://api.weather.gov/stations/${station.id}/observations/latest`);
type: 'GET',
url: `https://api.weather.gov/stations/${station.id}/observations/latest`,
dataType: 'json',
crossDomain: true,
});
// format the return values // format the return values
return Object.assign({}, data.properties, { return Object.assign({}, data.properties, {
StationId: station.id, StationId: station.id,

View file

@ -94,14 +94,10 @@ class LocalForecast extends WeatherDisplay {
let units = 'us'; let units = 'us';
if (navigation.units() === UNITS.metric) units = 'si'; if (navigation.units() === UNITS.metric) units = 'si';
try { try {
return await $.ajax({ return await utils.fetch.json(weatherParameters.forecast, {
type: 'GET',
url: weatherParameters.forecast,
data: { data: {
units, units,
}, },
dataType: 'json',
crossDomain: true,
}); });
} catch (e) { } catch (e) {

View file

@ -57,7 +57,7 @@ const navigation = (() => {
const point = await utils.weather.getPoint(latLon.lat, latLon.lon); const point = await utils.weather.getPoint(latLon.lat, latLon.lon);
// get stations // get stations
const stations = utils.fetch.json(point.properties.observationStations); const stations = await utils.fetch.json(point.properties.observationStations);
const StationId = stations.features[0].properties.stationIdentifier; const StationId = stations.features[0].properties.stationIdentifier;
@ -68,7 +68,6 @@ const navigation = (() => {
city = city.split('/')[0]; city = city.split('/')[0];
} }
// populate the weather parameters // populate the weather parameters
weatherParameters.latitude = latLon.lat; weatherParameters.latitude = latLon.lat;
weatherParameters.longitude = latLon.lon; weatherParameters.longitude = latLon.lon;

View file

@ -59,15 +59,10 @@ class Radar extends WeatherDisplay {
let radarHtml; let radarHtml;
try { try {
// get a list of available radars // get a list of available radars
radarHtml = await $.ajaxCORS({ radarHtml = await utils.fetch.text(baseUrl, {cors: true});
type: 'GET',
url: baseUrl,
dataType: 'text',
crossDomain: true,
});
} catch (e) { } catch (e) {
console.error('Unable to get list of radars'); console.log('Unable to get list of radars');
console.error(e.status, e.responseJSON); console.error(e);
this.setStatus(STATUS.failed); this.setStatus(STATUS.failed);
return; return;
} }
@ -143,19 +138,13 @@ class Radar extends WeatherDisplay {
context.imageSmoothingEnabled = false; context.imageSmoothingEnabled = false;
// get the image // get the image
const [blob, status, xhr] = await (()=>new Promise((resolve, reject) => { const response = await fetch(utils.cors.rewriteUrl(baseUrl + url));
$.ajaxCORS({
type: 'GET',
url: baseUrl + url,
xhrFields: {
responseType: 'blob',
},
crossDomain: true,
success: (blob, status, xhr) => resolve([blob,status,xhr]),
error: (xhr, status, e) => reject(e),
});
}))(); // test response
if (!response.ok) throw new Error(`Unable to fetch radar error ${response.status} ${response.statusText} from ${response.url}`);
// get the blob
const blob = await response.blob();
// store the time // store the time
const timeMatch = url.match(/_(\d{4})(\d\d)(\d\d)_(\d\d)(\d\d)_/); const timeMatch = url.match(/_(\d{4})(\d\d)(\d\d)_(\d\d)(\d\d)_/);
@ -171,7 +160,7 @@ class Radar extends WeatherDisplay {
zone: 'UTC', zone: 'UTC',
}).setZone(); }).setZone();
} else { } else {
time = DateTime.fromHTTP(xhr.getResponseHeader('Last-Modified')).setZone(); time = DateTime.fromHTTP(response.headers.get('last-modified')).setZone();
} }
// assign to an html image element // assign to an html image element

View file

@ -74,11 +74,7 @@ class RegionalForecast extends WeatherDisplay {
// start off the observation task // start off the observation task
const observationPromise = this.getRegionalObservation(point, city); const observationPromise = this.getRegionalObservation(point, city);
const forecast = await $.ajax({ const forecast = await utils.fetch.json(point.properties.forecast);
url: point.properties.forecast,
dataType: 'json',
crossDomain: true,
});
// get XY on map for city // get XY on map for city
const cityXY = this.getXYForCity(city, minMaxLatLon.maxLat, minMaxLatLon.minLon, weatherParameters.state); const cityXY = this.getXYForCity(city, minMaxLatLon.maxLat, minMaxLatLon.minLon, weatherParameters.state);
@ -109,8 +105,8 @@ class RegionalForecast extends WeatherDisplay {
this.buildForecast(forecast.properties.periods[2], city, cityXY), this.buildForecast(forecast.properties.periods[2], city, cityXY),
]; ];
} catch (e) { } catch (e) {
console.log(`No regional forecast data for '${city.Name}'`); console.log(`No regional forecast data for '${city.name}'`);
console.error(e.status, e.responseJSON); console.log(e);
return false; return false;
} }
}); });
@ -151,22 +147,12 @@ class RegionalForecast extends WeatherDisplay {
async getRegionalObservation (point, city) { async getRegionalObservation (point, city) {
try { try {
// get stations // get stations
const stations = await $.ajax({ const stations = await utils.fetch.json(point.properties.observationStations);
type: 'GET',
url: point.properties.observationStations,
dataType: 'json',
crossDomain: true,
});
// get the first station // get the first station
const station = stations.features[0].id; const station = stations.features[0].id;
// get the observation data // get the observation data
const observation = await $.ajax({ const observation = await utils.fetch.json(`${station}/observations/latest`);
type: 'GET',
url: `${station}/observations/latest`,
dataType: 'json',
crossDomain: true,
});
// preload the image // preload the image
utils.image.preload(icons.getWeatherRegionalIconFromIconLink(observation.properties.icon, !observation.properties.daytime)); utils.image.preload(icons.getWeatherRegionalIconFromIconLink(observation.properties.icon, !observation.properties.daytime));
// return the observation // return the observation

View file

@ -35,11 +35,7 @@ class TravelForecast extends WeatherDisplay {
try { try {
// get point then forecast // get point then forecast
const point = await utils.weather.getPoint(city.Latitude, city.Longitude); const point = await utils.weather.getPoint(city.Latitude, city.Longitude);
const forecast = await $.ajax({ const forecast = await utils.fetch.json(point.properties.forecast);
url: point.properties.forecast,
dataType: 'json',
crossDomain: true,
});
// determine today or tomorrow (shift periods by 1 if tomorrow) // determine today or tomorrow (shift periods by 1 if tomorrow)
const todayShift = forecast.properties.periods[0].isDaytime? 0:1; const todayShift = forecast.properties.periods[0].isDaytime? 0:1;
// return a pared-down forecast // return a pared-down forecast

View file

@ -7,16 +7,10 @@ const utils = (() => {
// ****************************** weather data ******************************** // ****************************** weather data ********************************
const getPoint = async (lat, lon) => { const getPoint = async (lat, lon) => {
try { try {
return await $.ajax({ return await json(`https://api.weather.gov/points/${lat},${lon}`);
type: 'GET',
url: `https://api.weather.gov/points/${lat},${lon}`,
dataType: 'json',
crossDomain: true,
});
} catch (e) { } catch (e) {
console.error('Unable to get point'); console.log(`Unable to get point ${lat}, ${lon}`);
console.error(lat,lon); console.error(e);
console.error(e.status, e.responseJSON);
return false; return false;
} }
}; };
@ -176,22 +170,56 @@ const utils = (() => {
// ********************************* cors ******************************************** // ********************************* cors ********************************************
// rewrite some urls for local server // rewrite some urls for local server
const rewriteUrl = (url) => { const rewriteUrl = (url) => {
url = url.replace('https://api.weather.gov/', ''); url = url.replace('https://api.weather.gov/', window.location.href);
url = url.replace('https://radar.weather.gov/', ''); url = url.replace('https://radar.weather.gov/', window.location.href);
url = url.replace('https://www.cpc.ncep.noaa.gov/', ''); url = url.replace('https://www.cpc.ncep.noaa.gov/', window.location.href);
return url; return url;
}; };
// ********************************* fetch ******************************************** // ********************************* fetch ********************************************
const json = async (url) => { const json = (url, params) => fetchAsync(url, 'json', params);
const response = await fetch(url, { const text = (url, params) => fetchAsync(url, 'text', params);
const raw = (url, params) => fetchAsync(url, '', params);
const blob = (url, params) => fetchAsync(url, 'blob', params);
const fetchAsync = async (_url, responseType, _params={}) => {
// combine default and provided parametersutils
const params = Object.assign({}, {
method: 'GET', method: 'GET',
mode: 'cors', mode: 'cors',
type: 'GET', type: 'GET',
},
_params);
// build a url, including the rewrite for cors if necessary
let corsUrl = _url;
if (params.cors === true) corsUrl = rewriteUrl(_url);
const url = new URL(corsUrl);
// add parameters if necessary
if (params.data) {
Object.keys(params.data).forEach((key) => {
// get the value
const value = params.data[key];
// add to the url
url.searchParams.append(key, value);
}); });
}
if (!response.ok) throw new Error(`Fetch error ${response.status} ${response.statusText} while fetching ${url}`); // make the request
const response = await fetch(url, params);
// check for ok response
if (!response.ok) throw new Error(`Fetch error ${response.status} ${response.statusText} while fetching ${response.url}`);
// return the requested response
switch (responseType) {
case 'json':
return await response.json(); return await response.json();
case 'text':
return await response.text();
case 'blob':
return await response.blob();
default:
return response;
}
}; };
// return an orderly object // return an orderly object
@ -233,15 +261,9 @@ const utils = (() => {
}, },
fetch: { fetch: {
json, json,
} text,
raw,
blob,
},
}; };
})(); })();
// pass data through local server as CORS workaround
$.ajaxCORS = function (e) {
// modify the URL
e.url = utils.cors.rewriteUrl(e.url);
// call the ajax function
return $.ajax(e);
};

View file

@ -1 +1 @@
module.exports = '3.5.1'; module.exports = '3.6.0';