orizens / ngx-typeahead

A simple but yet powerful typeahead component for Angular (css framework agnostic)
https://www.npmjs.com/package/ngx-typeahead
MIT License
61 stars 29 forks source link

TypeError: Cannot read property 'createEmbeddedView' of undefined #48

Open alsoicode opened 4 years ago

alsoicode commented 4 years ago

When using Angular 9.0 or above, I receive the following error:

core.js:6189 ERROR TypeError: Cannot read property 'createEmbeddedView' of undefined
    at ViewContainerRef.createEmbeddedView (core.js:15442)
    at NgxTypeAheadComponent.renderTemplate (ngx-typeahead.js:333)
    at NgxTypeAheadComponent.ngOnInit (ngx-typeahead.js:320)
    at callHook (core.js:4690)
    at callHooks (core.js:4654)
    at executeInitAndCheckHooks (core.js:4595)
    at refreshView (core.js:11875)
    at refreshDynamicEmbeddedViews (core.js:13220)
    at refreshView (core.js:11880)
    at refreshComponent (core.js:13295)
    at refreshChildComponents (core.js:11586)
    at refreshView (core.js:11909)
    at refreshComponent (core.js:13295)
    at refreshChildComponents (core.js:11586)
    at refreshView (core.js:11909)

With the following template code:

<input ngxTypeahead [taUrl]="typeaheadURL" [taApi]="'http'" [taQueryParam]="'term'" [taDebounce]="500" [taItemTpl]="itemTpl" (taSelected)="handleResultSelected($event)" type="text" class="form-control" formControlName="criteria" />
<ng-template #itemTpl let-result>
  {{ result.desc }}
</ng-template>
georgediaz88 commented 4 years ago

Any update on this? I'm also experiencing the same issue trying to upgrade a project to Angular 9.x. Thanks.

SamWolfs commented 4 years ago

@orizens I looked into the issue and it appears to be related to: https://angular.io/guide/migration-dynamic-flag As I currently see it, there are two options to resolve this: migrate to Angular 9 and make suggestionTplRef static or move the renderTemplate() function to the ngAfterViewInit() hook. Both solutions are outlined below.

Angular 9 migration

@ViewChild('suggestionsTplRef', { read: TemplateRef, static: true })
  suggestionsTplRef!: TemplateRef<any>;

with ngAfterViewInit()

renderTemplate() {
    const embeddedViewRef = this.viewContainer.createEmbeddedView(this.suggestionsTplRef);
    // prevents change detection errors
    embeddedViewRef.detectChanges();
    this.cdr.markForCheck();
  }

ngOnInit() {
    this.filterEnterEvent(this.keydown$);
    this.listenAndSuggest(this.keyup$);
    this.navigateWithArrows(this.keydown$);
  }

ngAfterViewInit() {
    this.renderTemplate();
}

As I've already performed all of the necessary work for the migration on my fork, I'd suggest this approach which should remain backwards compatible as the final build will keep using the old view engine (as recommended by the Angular Dev team).

Please advice and I will make a pull request accordingly.

orizens commented 4 years ago

hi @SamWolfs thanks for your comment. feel free to open a pr.

orizens commented 4 years ago

@SamWolfs upgrade to ng9 has started within this branch https://github.com/orizens/ngx-typeahead/tree/feautre/migrate-ng9 npm run build does not produce the final build yet. you're welcome to contribute