RadAutoCompleteTextView: Using Async Data Fetch

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 asyncronously 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 asyncronously 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 of the RadAutoCompleteTextView object.
The autocomplete executes this promise every time a symbol is typed and then generates
suggestions based on the colletion returned by the promise.

Create a page with RadAutoCompleteTextView control. 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 suggestionItemTemplate which will represent each suggestion.

<navigation:ExamplePage loaded="onPageLoaded" xmlns:navigation="navigation/example-page" xmlns:lv="nativescript-telerik-ui-pro/autocomplete" xmlns="http://www.nativescript.org/tns.xsd">
    <StackLayout ios:backgroundColor="#CDCECE" padding="5">
        <Label text="Select destination:"></Label>
        <lv:RadAutoCompleteTextView id="autocmp" items="{{ dataItems }}" suggestMode="Suggest" displayMode="Plain" showCloseButton="true" closeButtonImageSrc="res://clear">

            <lv:RadAutoCompleteTextView.suggestionView>
                <lv:SuggestionView suggestionViewHeight="300">
                    <lv:SuggestionView.suggestionItemTemplate>
                        <StackLayout orientation="vertical" padding="10">
                            <Label text="{{ text }}"></Label>

                        </StackLayout>
                    </lv:SuggestionView.suggestionItemTemplate>
                </lv:SuggestionView>
            </lv:RadAutoCompleteTextView.suggestionView>
         </lv:RadAutoCompleteTextView>
    </StackLayout>
</navigation:ExamplePage>

Retrieve the RadAutoCompleteTextView object that was initialized in the xml file and set it's loadSuggestionsAsync
property to e function which accepts one parameter (the typed text).
In this function define a promise, load the remote data in it and then return the promise.

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.

export class ViewModel extends observableModule.DependencyObservable {

    private _items: ObservableArray<autocompleteModule.TokenModel>;
    private autocmp;
    private countries = ["Australia", "Albania","Austria", "Argentina", "Maldives","Bulgaria","Belgium","Cyprus","Italy","Japan",
                                        "Denmark","Finland","France","Germany","Greece","Hungary","Ireland",
                                        "Latvia","Luxembourg","Macedonia","Moldova","Monaco","Netherlands","Norway",
                                        "Poland","Romania","Russia","Sweden","Slovenia","Slovakia","Turkey","Ukraine",
                                        "Vatican City", "Chad", "China", "Chile"];

    constructor(args) {
        super();
        var page = args.object;
        this.autocmp = page.getViewById("autocmp");
        this.autocmp.loadSuggestionsAsync = function(text) {
            var promise = new Promise( function(resolve, reject) {
                http.getJSON("http://www.telerik.com/docs/default-source/ui-for-ios/airports.json?sfvrsn=2").then(function(r:any){
                var airportsCollection = r.airports;
                var items:Array<autocompleteModule.TokenModel> = new Array();
                for (var i = 0; i < airportsCollection.length; i++) {
                    items.push(new autocompleteModule.TokenModel(airportsCollection[i].FIELD2, null));
                }
                resolve(items);
                }, function (e) {
                    reject();
                });
            });

            return promise;
        }
    }

    get dataItems() {
        return this._items;
    }
}
var ViewModel = (function (_super) {
    __extends(ViewModel, _super);
    function ViewModel(args) {
        _super.call(this);
        this.countries = ["Australia", "Albania", "Austria", "Argentina", "Maldives", "Bulgaria", "Belgium", "Cyprus", "Italy", "Japan",
            "Denmark", "Finland", "France", "Germany", "Greece", "Hungary", "Ireland",
            "Latvia", "Luxembourg", "Macedonia", "Moldova", "Monaco", "Netherlands", "Norway",
            "Poland", "Romania", "Russia", "Sweden", "Slovenia", "Slovakia", "Turkey", "Ukraine",
            "Vatican City", "Chad", "China", "Chile"];
        var page = args.object;
        this.autocmp = page.getViewById("autocmp");
        this.autocmp.loadSuggestionsAsync = function (text) {
            var promise = new Promise(function (resolve, reject) {
                http.getJSON("http://www.telerik.com/docs/default-source/ui-for-ios/airports.json?sfvrsn=2").then(function (r) {
                    var airportsCollection = r.airports;
                    var items = new Array();
                    for (var i = 0; i < airportsCollection.length; i++) {
                        items.push(new autocompleteModule.TokenModel(airportsCollection[i].FIELD2, null));
                    }
                    resolve(items);
                }, function (e) {
                    reject();
                });
            });
            return promise;
        };
    }
    Object.defineProperty(ViewModel.prototype, "dataItems", {
        get: function () {
            return this._items;
        },
        enumerable: true,
        configurable: true
    });
    return ViewModel;
}(observableModule.DependencyObservable));
exports.ViewModel = ViewModel;

References

Want to see this scenario in action?
Check our SDK examples repo on GitHub. You will find this and many other practical examples with NativeScript UI.