diff --git a/docs/source/documentation.html.md.erb b/docs/source/documentation.html.md.erb
index de7a366c5..8b1f03e32 100644
--- a/docs/source/documentation.html.md.erb
+++ b/docs/source/documentation.html.md.erb
@@ -384,6 +384,30 @@ and no suggestion is displayed nor selected.
You can use this event when used with a map to reset the pins and the default center. See this behaviour
live on the [map example](examples.html#link-to-a-map).
+
+
+
+
+ limit
+
+Event data: `undefined`
+
+ |
+
+Fired when you reached your current [rate limit](#rate-limits).
+ |
+
+
+
+ error
+
+ Event data:
+
+ - *message* Type: **string**
+
+ |
+
+ Fired when we could not make the request to Algolia Places servers for any reason but reaching your rate limit.
|
@@ -753,6 +777,8 @@ The Algolia Places API enforces some rate limits.
If you're calling the API from your backend, the rate-limits computation is then based on the source IP.
+If you are using the places.js library, you will receive a [`limit` event](#api-events-limit) on the places.js instance when you reach your current rate limit.
+
## License
Algolia Places [is licensed](https://github.com/algolia/places/blob/master/LICENSE) under [MIT](https://en.wikipedia.org/wiki/MIT_License).
diff --git a/src/createAutocompleteDataset.js b/src/createAutocompleteDataset.js
index 7965b8870..00fb7508b 100644
--- a/src/createAutocompleteDataset.js
+++ b/src/createAutocompleteDataset.js
@@ -7,11 +7,13 @@ export default function createAutocompleteDataset(options) {
...options.templates
};
+ const source = createAutocompleteSource({
+ ...options,
+ formatInputValue: templates.value
+ });
+
return {
- source: createAutocompleteSource({
- ...options,
- formatInputValue: templates.value
- }),
+ source,
templates,
displayKey: 'value',
name: 'places'
diff --git a/src/createAutocompleteSource.js b/src/createAutocompleteSource.js
index 713372ac0..7d479bb33 100644
--- a/src/createAutocompleteSource.js
+++ b/src/createAutocompleteSource.js
@@ -15,6 +15,8 @@ export default function createAutocompleteSource({
useDeviceLocation = false,
language = navigator.language.split('-')[0],
onHits = () => {},
+ onError,
+ onRateLimitReached,
type
}) {
const placesClient = algoliasearch.initPlaces(
@@ -75,5 +77,13 @@ export default function createAutocompleteSource({
return hits;
}
)
- .then(cb);
+ .then(cb)
+ .catch(e => {
+ if (e.message === 'Too many requests') {
+ onRateLimitReached();
+ return;
+ }
+
+ onError(e);
+ });
}
diff --git a/src/places.js b/src/places.js
index 68f250648..050c690e3 100644
--- a/src/places.js
+++ b/src/places.js
@@ -75,7 +75,25 @@ export default function places(options) {
rawAnswer,
query,
suggestions: hits
- })
+ }),
+ onError: e => placesInstance.emit('error', e),
+ onRateLimitReached: () => {
+ const listeners = placesInstance.listenerCount('limit');
+ if (listeners === 0) {
+ console.log(
+`Algolia Places: Current rate limit reached.
+
+Sign up for a free 100,000 queries/month account at
+https://www.algolia.com/users/sign_up/places.
+
+Or upgrade your 100,000 queries/month plan by contacting us at
+https://community.algolia.com/places/contact.html.`
+);
+ return;
+ }
+
+ placesInstance.emit('limit');
+ }
});
const autocompleteInstance = autocomplete(container, autocompleteOptions, autocompleteDataset);
const autocompleteContainer = container.parentNode;