I am using PlacesSearchBar to provide a autocomplete option to look up places in my Xamarin Forms application.
This is working fine from the component's point of view, but google API is returning me OVER_QUERY_LIMIT
after one or two attempts.
I think I know what the issue is here, this component is making more than one call to this google API per second that puts me as a suspect mode on the google logic and it starts to return me the OVER_QUERY_LIMIT
status. However I am unable to see how to introduce a delay between these calls.
here is how I am using this component.
<searchplaces:PlacesBar x:Name="edtSearch" MinimumSearchText="6" ApiKey="<API KEY>" Placeholder="Please enter your destination address"></searchplaces:PlacesBar>
<AbsoluteLayout>
<ActivityIndicator x:Name="spinner" IsRunning="false" AbsoluteLayout.LayoutBounds="0.5, 0.1, 50, 50" AbsoluteLayout.LayoutFlags="PositionProportional" />
<ListView x:Name="lvPlaces" ItemsSource="{Binding .}" RowHeight="60"
VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"
IsVisible="False" AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="SizeProportional">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="#2B2C30" Orientation="Vertical" Margin="0,0,0,2" Padding="5,5,5,5" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" >
<Label Text="{Binding Description}" TextColor="#EAEDF7" FontSize="Medium" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</AbsoluteLayout>
on my .cs
constructor I have this:
edtSearch.TextChanged += async (sender, e) =>
{
if (!string.IsNullOrEmpty(e.NewTextValue) && (e.NewTextValue.Length >= edtSearch.MinimumSearchText))
{
lvPlaces.IsVisible = false;
spinner.IsVisible = true;
spinner.IsRunning = true;
edtSearch.IsReadOnly = true; // try 1: to introduce delay
await Task.Delay(800);
}
else
{
lvPlaces.IsVisible = true;
spinner.IsRunning = false;
spinner.IsVisible = false;
edtSearch.IsReadOnly = false;
}
};
edtSearch.PlacesRetrieved = async (sender, result) =>
{
this.BindingContext = result.AutoCompletePlaces;
spinner.IsRunning = false;
spinner.IsVisible = false;
edtSearch.IsReadOnly = false;
if (result.AutoCompletePlaces != null && result.AutoCompletePlaces.Count > 0)
lvPlaces.IsVisible = true;
if (result.Status == "OVER_QUERY_LIMIT")
{
await Task.Delay(2000); // try 2: to introduce delay
}
};
edtSearch.MinimumSearchText = 6;
on the PlacesSearchBar component code I see this logic:
async void OnTextChanged(object sender, TextChangedEventArgs e)
{
if (!string.IsNullOrEmpty(e.NewTextValue) && e.NewTextValue.Length >= MinimumSearchText)
{
var predictions = await Places.GetPlaces(e.NewTextValue, ApiKey, Bias, Components, Type, Language);
if (PlacesRetrieved != null && predictions != null)
OnPlacesRetrieved(predictions);
else
OnPlacesRetrieved(new AutoCompleteResult());
}
else
{
OnPlacesRetrieved(new AutoCompleteResult());
}
}
as this is a event, no matter what I do from outside this component, it does not effect this behavior of the original component.
How can I get over this OVER_QUERY_LIMIT
when using this Auto complete text box
?
I think we managed to solve this, issue was that we has not connected our project to a billing account as a result there is a bare minimal request something of the order of 1 request per every second that google allows.
once we connected to a billing account this started to work at least for now.