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 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 tkSuggestionItemTemplate which will represent each suggestion in the tkAutoCompleteSuggestionView.
  • Finally retrieve the RadAutoCompleteTextView instance that was initialized in the HTML in our case using @ViewChild with a identifier 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 functionality.

<RadAutoCompleteTextView #autocmp [items]="dataItems" suggestMode="Suggest" displayMode="Plain">
    <SuggestionView tkAutoCompleteSuggestionView suggestionViewHeight="300">
        <ng-template tkSuggestionItemTemplate let-item="item">
            <StackLayout orientation="vertical" padding="10">
                <Label [text]="item.text"></Label>
            </StackLayout>
        </ng-template>
    </SuggestionView>
</RadAutoCompleteTextView>
import { Component, ViewChild, OnInit } from "@angular/core";
import { ObservableArray } from "tns-core-modules/data/observable-array";
import { TokenModel } from "nativescript-pro-ui/autocomplete";
import { RadAutoCompleteTextViewComponent } from "nativescript-pro-ui/autocomplete/angular";
import http = require("tns-core-modules/http");

@Component({
    moduleId: module.id,
    selector: "tk-autocomplete-remote.component",
    templateUrl: "autocomplete-remote.component.html"
})
export class AutoCompleteRemoteComponent implements OnInit {
    private _items: ObservableArray<TokenModel>;
    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"];

    ngOnInit() {
        this.autocmp.autoCompleteTextView.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<TokenModel> = new Array();
                    for (var i = 0; i < airportsCollection.length; i++) {
                        items.push(new TokenModel(airportsCollection[i].FIELD2, null));
                    }

                    resolve(items);
                }, function (e) {
                    reject();
                });
            });

            return promise;
        }
    }

    @ViewChild("autocmp") autocmp: RadAutoCompleteTextViewComponent;

    get dataItems(): ObservableArray<TokenModel> {
        return this._items;
    }

    private initDataItems() {
        this._items = new ObservableArray<TokenModel>();

        for (var i = 0; i < this.countries.length; i++) {
            this._items.push(new TokenModel(this.countries[i], undefined));
        }
    }
}

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.