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;