Using Async Data Fetch with RadAutoCompleteTextView
There are multiple scenarios where we need to represent data loaded from remote provider like a web service. Dynamic loading of items, based on the user input, could be quite useful when we are working with sets of data that are not available locally. In order to satisfy this scenario, the autocomplete provides you with API, which allows you asynchronously to load your data and then pass it to the control.
In next section we will discuss the process of working with remote data in details. For the purpose of the example we will use json data containing description of airports.
Implementation
Populating the autocomplete asynchronously is quite straightforward task. All you need is a promise which should handle
the data fetch and return a collection of TokenModel
objects.
You should assign this promise to the loadSuggestionsAsync
property.
The autocomplete executes this promise every time a symbol is typed and then generates
suggestions based on the collection returned by the promise.
- First you need to add the
RadAutoCompleteTextView
to your component's HTML. - Setup the control in a way that suits you and bind it to source collection, which in our case is called
dataItems
. - Do not forget to provide a
v-suggestionItemTemplate
which will represent each suggestion in theSuggestionView
. - Finally retrieve the
RadAutoCompleteTextView
instance that was initialized in the HTML in our case using @ViewChild with a identifier and set it'sloadSuggestionsAsync
property to a function which accepts one parameter (the typed text). In this function define aPromise
, load the remote data in it and then return thePromise
.
Later on the autocomplete will invoke the loadSuggestionsAsync
function and when the promise is resolved,
it will use the returned items to complete it's population functionality.
export default {
name: 'AsyncData',
description: description,
template: `
<Page>
<ActionBar :title="title">
<NavigationButton text="Back" android.systemIcon="ic_menu_back" @tap="onNavigationButtonTap"></NavigationButton>
</ActionBar>
<StackLayout ios:backgroundColor="#CDCECE" padding="5">
<Label text="Select airport"></Label>
<RadAutoCompleteTextView ref="autocomplete"
displayMode="plain"
suggestMode="Suggest"
:items="dataItems">
<SuggestionView ~suggestionView suggestionViewHeight="300">
<StackLayout v-suggestionItemTemplate orientation="vertical" padding="10">
<v-template>
<Label :text="item.text"></Label>
</v-template>
</StackLayout>
</SuggestionView>
</RadAutoCompleteTextView>
</StackLayout>
</Page>
`,
data () {
return {
title: description,
dataItems: new ObservableArray(),
};
},
methods: {
onNavigationButtonTap() {
Frame.topmost().goBack();
},
},
mounted () {
const jsonUrl = 'https://raw.githubusercontent.com/NativeScript/nativescript-ui-samples/master/examples-data/airports.json';
this.$refs.autocomplete.setLoadSuggestionsAsync((text) => {
const promise = new Promise((resolve, reject) => {
http.getJSON(jsonUrl).then((r: any) => {
const airportsCollection = r.airports;
const items: Array<TokenModel> = new Array();
for (let i = 0; i < airportsCollection.length; i++) {
items.push(new TokenModel(airportsCollection[i].FIELD2, null));
}
resolve(items);
}).catch((err) => {
const message = `Error fetching remote data from ${jsonUrl}: ${err.message}`;
console.log(message);
alert(message);
reject();
});
});
return promise;
});
},
};