1

Probably a dumb question but I'm trying to get remote data to use in nativescript-ui-autocomplete but I get the following error ERROR TypeError: Cannot set property 'loadSuggestionsAsync' of undefined

The code is very similar to the example at https://github.com/NativeScript/nativescript-ui-samples-angular/tree/master/autocomplete/app/examples/remote-data-fetch however I can't get mine to work.

TypeScript

import * as http from "tns-core-modules/http";

import { ObservableArray } from "tns-core-modules/data/observable-array";
import { TokenModel } from "nativescript-ui-autocomplete";
import { RadAutoCompleteTextViewComponent } from "nativescript-ui-autocomplete/angular";

export class MapComponent implements OnInit {

    private _items: ObservableArray<TokenModel>;
    private jsonUrl = "https://raw.githubusercontent.com/NativeScript/nativescript-ui-samples/master/examples-data/airports.json";

    mapbox: MapboxViewApi; 

    constructor( private router: Router) {
        // Use the component constructor to inject providers.
    }

    ngOnInit() {
        let that = this;
        this.autocomplete.autoCompleteTextView.loadSuggestionsAsync = function (text) {
            const promise = new Promise(function (resolve, reject) {
                http.getJSON(that.jsonUrl).then(function (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 ' + that.jsonUrl + ': ' + err.message;
                    console.log(message);
                    alert(message);
                    reject();
                });
            });

            return promise;
        };

    }

    @ViewChild("autocomplete", { static: true }) autocomplete: RadAutoCompleteTextViewComponent;

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

XML

<RadAutoCompleteTextView #autocomplete [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> 

I also tried it on a blank project but same error

EDIT: Tried reproducing in playground and it works without problems, I copy the code to my project and get the same error, tried putting everything in a try/catch and got this after the error

ERROR Error: Uncaught (in promise): Error: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources$Theme android.content.Context.getTheme()' on a null object reference
JS: createAlertDialog(file: node_modules\@nativescript\core\ui\dialogs\dialogs.android.js:12:0)
JS:     at (file: node_modules\@nativescript\core\ui\dialogs\dialogs.android.js:96:0)
JS:     at ZoneAwarePromise(file: node_modules\@nativescript\angular\zone-js\dist\zone-nativescript.js:902:0)
JS:     at alert(file: node_modules\@nativescript\core\ui\dialogs\dialogs.android.js:93:0)
JS:     at push../app/map/map.component.ts.MapComponent.ngAfterViewInit(file: src\app\map\map.component.ts:61:12)
JS:     at callProviderLifecycles(file: node_modules\@angular\core\fesm5\core.js:21414:0)
JS:     at callElementProvidersLifecycles(file: node_modules\@angular\core\fesm5\core.js:21388:0)
JS:     at callLifecycleHooksChildrenFirst(file:///data/data/org.nativescript.MapboxEnduco/files/app...
Diogo Santos
  • 49
  • 1
  • 5
  • Can you share a Playground sample where the issue can be reproduced. – Manoj Mar 31 '20 at 21:49
  • @Manoj Updated original post – Diogo Santos Mar 31 '20 at 22:20
  • Looks the the error was thrown from alert dialog itself. If you comment all dialogs or may be replace it with logs, still you see the same error? – Manoj Apr 01 '20 at 01:27
  • @Manoj Yeah that was a problem with the try/catch I wrote, no longer happens. The weird thing is I copy the code from the example into playground, works. I download the playground and run it locally, works. I create a new angular app with tns create and copy the code, doesn't work. – Diogo Santos Apr 01 '20 at 12:14

3 Answers3

0

Try ngAfterViewInit(). ngAfterViewInit() is called after the view is initially rendered. This is why @ViewChild() depends on it.

ngAfterViewInit() {
        let that = this;
        this.autocomplete.autoCompleteTextView.loadSuggestionsAsync = function (text) {
            const promise = new Promise(function (resolve, reject) {
                http.getJSON(that.jsonUrl).then(function (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 ' + that.jsonUrl + ': ' + err.message;
                    console.log(message);
                    alert(message);
                    reject();
                });
            });

            return promise;
        };

    }
0

Had the same issue, in my case, I had to replace

 this.autocomplete.*autoCompleteTextView*.loadSuggestionsAsync = function (text) {

with

this.autocomplete.**nativeElement**.loadSuggestionsAsync = function (text) { //etc

Hope it will help you.

Tom Carrick
  • 6,349
  • 13
  • 54
  • 78
0

In my case. I moved the component declaration to one module up. And it helped. Maybe it needs some special modules, but I didn't find any info in the documentation.