diff --git a/examples/vector-esri.js b/examples/vector-esri.js index cb28556a4d..ad018becdb 100644 --- a/examples/vector-esri.js +++ b/examples/vector-esri.js @@ -56,7 +56,7 @@ const styleCache = { }; const vectorSource = new VectorSource({ - loader: function (extent, resolution, projection) { + loader: function (extent, resolution, projection, success, failure) { const url = serviceUrl + layer + @@ -83,6 +83,7 @@ const vectorSource = new VectorSource({ alert( response.error.message + '\n' + response.error.details.join('\n') ); + failure(); } else { // dataProjection will be read from document const features = esrijsonFormat.readFeatures(response, { @@ -91,8 +92,10 @@ const vectorSource = new VectorSource({ if (features.length > 0) { vectorSource.addFeatures(features); } + success(features); } }, + error: failure, }); }, strategy: tileStrategy( diff --git a/examples/vector-osm.js b/examples/vector-osm.js index a5ad295b26..3b9b4faf80 100644 --- a/examples/vector-osm.js +++ b/examples/vector-osm.js @@ -74,7 +74,7 @@ const styles = { const vectorSource = new VectorSource({ format: new OSMXML(), - loader: function (extent, resolution, projection) { + loader: function (extent, resolution, projection, success, failure) { const epsg4326Extent = transformExtent(extent, projection, 'EPSG:4326'); const client = new XMLHttpRequest(); client.open('POST', 'https://overpass-api.de/api/interpreter'); @@ -83,7 +83,9 @@ const vectorSource = new VectorSource({ featureProjection: map.getView().getProjection(), }); vectorSource.addFeatures(features); + success(features); }); + client.addEventListener('error', failure); const query = '(node(' + epsg4326Extent[1] + diff --git a/src/ol/featureloader.js b/src/ol/featureloader.js index 6247be210d..dbe2ae092f 100644 --- a/src/ol/featureloader.js +++ b/src/ol/featureloader.js @@ -15,10 +15,12 @@ let withCredentials = false; * {@link module:ol/source/Vector} sources use a function of this type to * load features. * - * This function takes an {@link module:ol/extent~Extent} representing the area to be loaded, - * a `{number}` representing the resolution (map units per pixel), an - * {@link module:ol/proj/Projection} for the projection and success and failure callbacks as - * arguments. `this` within the function is bound to the + * This function takes up to 5 arguments. These are an {@link module:ol/extent~Extent} representing + * the area to be loaded, a `{number}` representing the resolution (map units per pixel), an + * {@link module:ol/proj/Projection} for the projection, an optional success callback that should get + * the loaded features passed as an argument and an optional failure callback with no arguments. If + * the callbacks are not used, the corresponding vector source will not fire `'featuresloadend'` and + * `'featuresloaderror'` events. `this` within the function is bound to the * {@link module:ol/source/Vector} it's called from. * * The function is responsible for loading the features and adding them to the diff --git a/src/ol/source/Vector.js b/src/ol/source/Vector.js index 1c36c542a6..38ad4ab5c6 100644 --- a/src/ol/source/Vector.js +++ b/src/ol/source/Vector.js @@ -72,7 +72,8 @@ export class VectorSourceEvent extends Event { * @property {import("../featureloader.js").FeatureLoader} [loader] * The loader function used to load features, from a remote source for example. * If this is not set and `url` is set, the source will create and use an XHR - * feature loader. + * feature loader. The `'featuresloadend'` and `'featuresloaderror'` events + * will only fire if the `success` and `failure` callbacks are used. * * Example: * @@ -83,7 +84,7 @@ export class VectorSourceEvent extends Event { * * var vectorSource = new Vector({ * format: new GeoJSON(), - * loader: function(extent, resolution, projection) { + * loader: function(extent, resolution, projection, success, failure) { * var proj = projection.getCode(); * var url = 'https://ahocevar.com/geoserver/wfs?service=WFS&' + * 'version=1.1.0&request=GetFeature&typename=osm:water_areas&' + @@ -93,12 +94,14 @@ export class VectorSourceEvent extends Event { * xhr.open('GET', url); * var onError = function() { * vectorSource.removeLoadedExtent(extent); + * failure(); * } * xhr.onerror = onError; * xhr.onload = function() { * if (xhr.status == 200) { - * vectorSource.addFeatures( - * vectorSource.getFormat().readFeatures(xhr.responseText)); + * var features = vectorSource.getFormat().readFeatures(xhr.responseText); + * vectorSource.addFeatures(features); + * success(features); * } else { * onError(); * }