Utilize object-based autocomplete instead of using arrays

I am currently exploring the usage of Autocomplete from Angular Material.

Instead of having their predefined data as

options: string[] = ['One', 'Two', 'Three'];
, I have my own object.

This is how I retrieve the data from my object, which is stored in a file called currencies.json:

list(): Observable<Currencies> {
  return this._http.get('./assets/currencies.json') as unknown as Observable<Currencies>;
}
public currencies$ = this.getAllCurrencies();

getAllCurrencies(): Observable<Currencies> {
  return this._currencyService.list();
}

Now, here's my approach to bind the autocomplete functionality:

<ng-container *ngIf="currencies$ | async">
  <mat-form-field appearance="fill">
    <mat-label>Currency</mat-label>
      <input id="currency" type="text" matInput placeholder="Select a currency. E.g. USD" [matAutocomplete]="auto" formControlName="currency">
      <mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
        <mat-option *ngFor="let currency of currencies$ | keyvalue" [value]="currency.key">
          {{currency.key}}
        </mat-option>
      </mat-autocomplete>
  </mat-form-field>
</ng-container>
this.currencies$ = this.formMain.valueChanges.pipe(
  startWith(''),
  map(value => this.currencies$.subscribe(data => data.currency.includes((value.toString().toUpperCase() || '')))),
);

However, encountering the following error:

TS2322: Type 'Observable' is not assignable to type 'Observable'. Property 'currency' is missing in type 'Subscription' but required in type 'Currencies'.

Any suggestions on how to rectify this issue?


Another attempt was made with the following code:

currencies?: Observable<string[]>;

this.currencies = this.formMain.valueChanges.pipe(
  startWith(''),
  map(value => this.currencies$.subscribe(data => data.currency.includes((value.toString().toUpperCase() || '')))),
);

But faced the subsequent error:

TS2322: Type 'Observable' is not assignable to type 'Observable'. Type 'Subscription' is missing the properties from type 'string[]': length, pop, push, concat, and more.

Attempting it without using subscribe():

this.formMain.valueChanges.pipe(
  startWith(''),
  map(value => [this.currencies$].filter(currency => currency.includes(value)))
);

And receiving this error:

TS2339: Property 'includes' does not exist on type 'Observable'.

You can check out my StackBlitz code along with the official Angular Material code on StackBlitz. My objective is to replicate the official code behavior using my custom data.

Answer №1

To start with, ensure you are using the correct interface for your object.

Consider the following code snippet:

export interface Currencies {
  currency: string;
}

This code indicates that your data should follow this format:

{
  currency: 'some string'
}

If your object differs, you can utilize:

export type Currencies = Record<string, string>;

Secondly, avoid casting your http call unnecessarily:

this._http.get('./assets/currencies.json') as unknown as Observable<Currencies>;

Instead, simply use the generic version of http.get<T> method:

this._http.get<Currencies>('./assets/currencies.json')
               ^^^^^^^^^^

Thirdly, make sure to utilize [formControl] binding in your stackblitz when a wrapper with formGroup is absent:

formControlName="currency" => [formControl]="myControl"

Lastly, when constructing the currencies$ observable, remember to work with Observable by using switchMap instead of the map rxjs operator:

currencies$ = this._currencyService.list().pipe(
  switchMap((currencies) => {
    return this.myControl.valueChanges.pipe(
      startWith(''),
      map((query) =>
        Object.fromEntries(
          Object.entries(currencies).filter(([key]) =>
            key.includes(query.toUpperCase())
          )
        )
      )
    );
  })
);

Take a look at the Forked Stackblitz

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

Struggling to render the template inside a .vue file in a Vue.js + TypeScript project?

Is anyone familiar with setting up a Vue TS based project? I have encountered an issue where the template data is not being rendered in the browser's DOM. The project structure can be found in this repository: https://github.com/AndrewBogdanovTSS/typ ...

Angular 5 Service Unit Testing for UPDATE Function

Currently, I am implementing a stepper feature with back, step, next steps. On the last step, when the user clicks 'done,' I need to call a service to update user data. While I have successfully tested the backStep() and nextStep() methods, I now ...

What steps do I need to take in order to develop a custom component for FormControls?

Trying to create a form with a custom component for controls, I encountered an issue. Despite including the new component in the parent form that already has a formGroup, Angular throws an error. The error I faced is: Error: formControlName must be use ...

Deploying an NX micro front-end using docker and Nginx individually for every micro front-end

In my Angular 16 application, I am currently using Nx Micro Front End (MFE) architecture with docker-compose for deployment. All my MFEs are working fine within the same Nginx setup. Now, I want to isolate each MFE into its own container so that they can ...

Managing several instances of NgbPagination on a single webpage

I am facing a challenge with having multiple NgbPagination components on a single page. For more information, please visit: Initially, I attempted to use ids but encountered an issue where changing one value in the first pagination affected both tables. ...

node-ts displays an error message stating, "Unable to locate the name '__DEV__' (TS2304)."

I recently inserted __DEBUG__ into a TypeScript file within my NodeJS project. Interestingly, in VSCode, no error is displayed. However, upon running the project, I encounter an immediate error: error TS2304: Cannot find name '__DEBUG__'. I att ...

Guidelines for transmitting form information to a web API using Angular

I am currently working on an Angular 6 project where I have a form and a table that retrieves data from a web API. I want to know if it's possible to send the form data to that web API. Here is the code snippet that I have so far: HTML Form: &l ...

What advantages does NgRx offer that Signal does not provide?

Signals are a recent addition to the Angular framework. In comparison to Signals, what unique benefits does the NgRx component store or other state management options provide? Are there any functionalities offered by the NgRx component store that cannot ...

The debate between using a Class and an Object Literal comes down to the immut

Is it possible to create read-only properties in object literals? export const Page = { email: 'input[type=email]', password: 'input[type=password]', fillLoginCredentials() { cy.get(this.email).type('email&a ...

Executing service calls in a for loop in Angular 2 using the Http module

Encountered a challenge with Angular 2 HTTP service call within a for loop. The for loop executes quickly compared to the slow result returned by the service call. this.projectService.addProjectServices(pid, rid, vname, field_name, ser_name).subscribe( ...

There seems to be an issue with the React Native FlatList: It appears that there is no overload matching this call and some

I am currently learning React Native and attempting to create a basic chat room application. I am facing an issue with the FlatList component that I can't seem to resolve. Even though I have provided both the data prop and renderItem prop to the FlatL ...

Difficulty rendering images and CSS during preloading in a Node.js environment

I'm aware of the necessity to use a middleware, but I need guidance on how to implement it correctly. Here is the snippet of code I currently have: const prerender = require('prerender'); var server = prerender({ chromeFlags: ['--no-s ...

Having difficulty retrieving an angular file from a location outside of the asset folder

I'm encountering issues with a small project that is meant to read a log and present it in table format. Here is the outline of the project structure: project structure Within the LOG directory, I should be able to access motore.log from my DataServi ...

Issues with loading Angular 6 project in Internet Explorer 11

My Angular 6 project is successfully loading in Chrome, however it is not working in IE11. I referred to the Stack Overflow question titled Angular 2 / 4 / 5 not working in IE11 for potential solutions, but unfortunately none of them resolved the issue. He ...

Bringing in additional types with the primary import using import/require

I am currently creating a definition file for Airtable, and I have encountered an issue with the way they export their classes. They only provide one class like this: ... module.exports = Airtable; As a result, my airtable.d.ts file looks something like ...

The radio button in Angular 6 is not selected

Below is a code snippet that I am working with: <div class="col-md-6 col-lg-6 col-xl-6 mb-5"> <label>Versioning</label><br/> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" n ...

Unable to install a specific commit of an angular library from GitHub using npm

While utilizing Angular 2.0.0-beta.15, I encountered the inability to upgrade it. Thus, I had to search for a specific commit from the ng2-dnd library on GitHub. Upon locating a compatible commit for version 2.0.0-beta.17: "ng2-dnd": "git://github.com/ak ...

Guide on transferring information obtained from a service to an Angular datatable

Recently, I started working on Angular 4 and encountered an issue while trying to display data from an Angular service in JSON format using angular-datatable. Despite trying various options, I am unable to get the data to display within the columns of the ...

What is the correct way to set up Typescript for usage with Angular 2 in Visual Studio 2015?

I recently created an Angular 2 app using Visual Studio 2015 and TypeScript. I made sure to install TypeScript globally using the npm command "npm install -g [email protected]." However, when I try to build the project, I encounter several errors re ...

Trouble with Typescript in VSCode made easy

Setting up a VSCode environment for working with TypeScript v2.03 has been challenging. Beginning with a simple vanilla javascript snippet that can be tested in node via the integrated terminal. function Person() { this.name = ""; } Person.prototy ...