The ngBootstraps typeahead is encountering an issue: It is unable to locate a supporting object with the type of 'object Promise'

Having an issue with ngBootstraps typeahead and async http requests.

This is what I have

example.html

<input id="typeahead-basic" type="text" class="form-control" value="{{issue.Series.Title}}" (selectItem)="selectSeries($event)" [ngbTypeahead]="searchSeries" [resultFormatter]="seriesFormatter"/>

example.ts

searchSeries = (text$: Observable<string>) =>
        text$
            .debounceTime(100)
            .distinctUntilChanged()
            .map(async term => {
                return await this.service.getSeries(term);
            });

example.servics.ts

  async getSeries(term: string): Promise<Series[]> {
    let series: Series = new Series();
    series.Title = term;

    let headers = new Headers();
    headers.append('Content-Type', 'application/json');
    let options = new RequestOptions({headers: headers});

    return await this.http.post(this.urlSeries, JSON.stringify(series), options)
        .map(res => res.json() || {})
        .catch(res => Observable.throw("error"))
        .toPromise();
  }    

Encountering an error every time I start typing in the input field.

NgbTypeaheadWindow.html:5 ERROR Error: Cannot find a differ supporting object '[object Promise]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
    at NgForOf.webpackJsonp.../../../common/@angular/common.es5.js.NgForOf.ngOnChanges (common.es5.js:1659)
    at checkAndUpdateDirectiveInline (core.es5.js:10891)
    at checkAndUpdateNodeInline (core.es5.js:12382)
    at checkAndUpdateNode (core.es5.js:12321)
    at debugCheckAndUpdateNode (core.es5.js:13180)
    at debugCheckDirectivesFn (core.es5.js:13121)
    at Object.eval [as updateDirectives] (NgbTypeaheadWindow.html:5)
    at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:13106)
    at checkAndUpdateView (core.es5.js:12288)
    at callViewAction (core.es5.js:12651)

The error message suggests that ngFor requires an Array, but my searchSeries function does return an array. When I modify searchSeries to

searchSeries = (text$: Observable<string>) =>
        text$
            .debounceTime(100)
            .distinctUntilChanged()
            .map(async term => {
                let result = await this.service.getSeries(term);
                console.log(result);
                return result;
            }); 

I can confirm that result is an array. So why am I still seeing this error message?

Appreciate any help!

Answer №1

To start, I recommend using RXJS with observables. Regarding the error message: the issue lies in this line of code: let result = await this.service.getSeries(term); As the result is now an observable, you cannot loop through it directly. If you want to resolve this without altering the implementation, simply wait for the HTTP request to complete before setting the result. If you are working with observables, you will need something like YOURREQUEST.subscribe(data => { let result = data }); I have not personally worked with Angular and promises. I also suggest checking out the example on the ngbootstrap demo page "Wikipedia search" https://ng-bootstrap.github.io/#/components/typeahead I hope this explanation is clear and apologize for any language barriers.

Answer №2

To tackle this issue, utilizing the switchMap operator can be quite beneficial. Referencing an example from Ng-bootstrap:

searchItems = (input$: Observable<string>) =>
    input$
      .debounceTime(400)
      .distinctUntilChanged()
      .do(() => this.isSearching = true)
      .switchMap(searchTerm =>
        this._dataService.searchForItem(searchTerm)
          .do(() => this.searchFailed = false)
          .catch(() => {
            this.searchFailed = true;
            return Observable.of([]);
          }))
      .do(() => this.isSearching = false)
      .merge(this.hideSearchWhenNoResults);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble with shared HTML in Angular 4 not functioning as thought?

I have implemented a shared HTML code for search functionality across multiple pages search.component.html <form class="p-2" (ngSubmit)="searchHere(query)" #customersearch="ngForm"> <div class="input-group custom-search-form float-right"> ...

A type in Typescript for nested properties of an object

I am striving to achieve a structure where the type of the Component can be automatically inferred and the props can be safely typed as well. type ComponentsType<T extends React.FC<any>> { [key: string]: { Component: T; props?: React. ...

What are some ways to utilize ngControl within a contenteditable element?

I need guidance on utilizing ngControl in a contenteditable element. Here is an example of what I am trying to achieve: <!-- *ngFor over rows and columns in table --> <td contenteditable="true" [ngControl]="row.number + column.number"></td& ...

Each time Angular 6 makes a server call, it consistently retrieves the same API data until the application is refreshed

I'm currently working on developing a dashboard for a Skype bot where I need to request data every 10 seconds. The issue I'm facing is that I keep getting the same data from the API each time, but upon refreshing the app, I receive updated data f ...

Discrepancies in output between grunt-ts and tsc

Currently, I have set up a tsconfig.json file in combination with grunt-ts for the following grunt task: ts: { default: { tsconfig: true } Here is the content of the tsconfig.json file: { "compilerOptions": { "target": "es5", "module ...

Refreshing the partial view using business logic

View: Index @{ ViewBag.Title = "Home Page"; } @section Content1 { <div> @Ajax.ActionLink("Just refresh", "_Test", "Home", null, new AjaxOptions() { UpdateTargetId = "ContentRefresh", HttpMethod = "Post ...

How can I dynamically resize an element based on the height of its content in Ionic?

Is there a way to make my element expand conditionally? I would like it to expand on click based on the height of its content. This is what the component's HTML looks like: <div class="container" [style.height]="enlarged === true ? ...

What sets apart gulp and webpack in an Angular 2 environment?

I've created a compact project that requires performance testing. For development, testing server and deployment of the Angular 2 app on IIS, which tool is more efficient - Webpack or Gulp? What are the key differences between Gulp and Webpack? ...

Converting React useState to a JSON object data type

I imported a JSON data file using the following code: import data from "../data.json"; The contents of the file are as follows: [ { "name": "Emery", }, { "name": "Astrid", }, { " ...

What is the best way to bundle a TypeScript package along with its dependencies for seamless integration with various Next.js projects on a local environment

Currently, I am immersed in a project with the following arrangement: / # repository root /core # A local, unpublished npm package used by both projectA and projectB /projectA # A Next.js app /projectB # Another Next.js app In my setup, I gene ...

Encountering a problem while installing an Angular 2 npm package from an enterprise registry

We are utilizing an enterprise repository for NPM packages that mirrors the traditional registry "http://registry.npmjs.org/". I am currently attempting to fetch the following packages (listed in package.json) "@angular/common": "2.0.0-rc.4", "@angular/co ...

Encountering an error when trying to set data in a Firestore document with a customized JavaScript object: "Invalid data provided for function DocumentReference.set()"

For my initial project, I need help in identifying where the issue lies. Firstly, I have a function that adds data to Firebase: addpost() { let newposts = new Posts( this.addForm.value ) this.postsservice.addPosts(newposts); } Ne ...

Frequent occurrence when a variable is utilized prior to being assigned

I am currently working with a module import pino, { Logger } from 'pino'; let logger: Logger; if (process.env.NODE_ENV === 'production') { const dest = pino.extreme(); logger = pino(dest); } if (process.env.NODE_ENV === &apo ...

Steps to showcase a HTML modal based on the outcome of a JavaScript/AJAX database query

Currently in the process of developing a Facebook game utilizing html and Javascript. With two modals on an html page (referred to as ModalA and ModalB), the goal is to link both modals to a single button, triggering the display of only one modal based on ...

Replace Angular Material Component with a new custom component in Angular

In order to customize the Angular Material select component (https://material.angular.io/components/select/overview) to have an input field transformed into an icon button, I attempted to override its styling. While this approach worked well for me, I came ...

Show personalized names for breadcrumb links in Angular5

I recently added the ng5-breadcrumb package to my project to show breadcrumbs on the website. Here are the code modifications I made: In app.module.ts import { Ng5BreadcrumbModule, BreadcrumbService } from 'ng5-breadcrumb'; imports: [ ... ...

Develop an "Import Interface" using TypeScript

I have a large project with many files and I believe using an import object would be beneficial. For instance, consider having menu.ts at the top level that every program will refer to: import router from "./router/index"; import controllers from ...

Obtain every selection from the multiselect box and add them to the database

How do I assign all selected measures to my "answers" object? The selected measures are: get selectedMeasures() { const items = this.measureItems.filter((item: any) => item.selected); return items.length ? JSON.stringify(items.map(item => ...

What steps are involved in creating an API with fastAPI that simply initiates the execution of another Python file for running a query, without pausing for its response?

Here is the code I am currently using to wait for a response. The 'details' variable represents a file that has been imported, and I am calling its 'get_query_status' method. @app.get("/trigger_query") def trigger_query(databa ...

Passing the value of an Angular component to a different component

I have a menu in my application that uses IDs to route content, and I also have a detailed view where the content should be displayed based on those same IDs. Currently, I am trying to display objects by their ID when a button is clicked. However, I' ...