Refining a Form Collection in Angular

I have a list of cars that I am converting into a FormArray to display as buttons in an HTML list. My goal is to filter these cars based on their names.

CarComponent.html

<input #searchBox id="search-box" (input)="search(searchBox.value)" />
<form [formGroup]="form" *ngIf="showCars">
    <input type="button" class ="btn"  formArrayName="carsList" *ngFor="let car of carsList$ | async; let i = index" value="{{carsList[i].name}}" >
</form>

CarComponent.ts

carsList$: Observable<Car[]>;
private searchTerms = new Subject<string>();
search(term: string): void {
    this.searchTerms.next(term);
}
    
constructor(private formBuilder:FormBuilder,...)
{
    this.form = this.formBuilder.group({
        carsList: new FormArray([])
    });
    
    this.addButtons();    
}
    
ngOnInit() {
    this.spinner.show(); 
    this.carsList$ = this.searchTerms.pipe(
        debounceTime(300),
        distinctUntilChanged(),
        switchMap((term:string)=> 
          this.carsList ??? // Is this correct ?? What do I put here? 
        )
}
    
private addButtons() {
          
    this.carsList.map((o,i)=>{
        const control = new FormControl;
        (this.form.controls.carsList as FormArray).push(control);
    })
}
    
export const CarsList: Car[] = [
    { name: 'Mercedes' },
    { name: 'BMW' },
    { name: 'Porsche' },
    { name: 'Cadillac' }
]

I'm looking for advice on how to efficiently filter the list without using a pipe for performance reasons.

Answer №1

Utilizing rxjs streams, you can handle everything declaratively. I have created a demonstration where each car is equipped with a FormControl to modify its name.

With the help of combineLatest, you can easily showcase the latest filter outcome whenever there is a search query or a change in a car's name.

Explore the working example on StackBlitz.

Component:

search = new Subject<string>();
carsList: Car[] = [{ name: 'Mercedes' }, { name: 'BMW' }, { name: 'Porsche' }, { name: 'Cadillac' }];

// Form Array of car names
carForm = this.formBuilder.array(this.carsList.map(car => car.name));

// Filtered car form controls based on name
filteredCarForm$ = combineLatest([
  this.search.pipe(debounceTime(300), startWith(''), distinctUntilChanged()),
  this.carForm.valueChanges.pipe(startWith(this.carForm.value))
]).pipe(
  map(([search]) =>
    this.carForm.controls.filter(carControl => carControl.value?.toLowerCase().includes(search.toLowerCase()))
  )
);

Template:

<input #searchBox (input)="search(searchBox.value)" />
<form>
  <input [formControl]="carControl" *ngFor="let carControl of filteredCarForm$ | async" />
</form>

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

Is it necessary to validate a token with each change of page?

Currently facing a dilemma while working on my react-native app. Uncertain whether I should request the server to validate the token each time the page/screen changes, such as switching from 'feed' to 'profile', or only when actual requ ...

Typescript's Nested Type Assignments

Simply put, I'm making an API call and receiving the following data: { getUserInfo: { country: 'DE', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3c48594f487c59445d514c5059125f5351">[e ...

Error TS2504: The data type 'ReadableStream<Uint8Array>' is required to include a method '[Symbol.asyncIterator]()' that outputs an asynchronous iterator

I'm attempting to utilize the body of a fetch response as an asynchronous iterable in a fresh CRA React application. const fetchedResponse = await fetch('example.com'); if (fetchedResponse.ok && fetchedResponse.body) { for aw ...

Struggling to grasp the concept of Observable Catch closure scope in Angular2?

Seeking guidance on using catch with Observables. I find myself confused and would appreciate some assistance. My goal is to handle a 403 error from the API by deleting the local token and marking the user as unauthenticated in my TokenStore. The approach ...

Setting up raw-loader in Angular 7 for loading text files

I am struggling to implement a raw-loader with my Angular 7 in order to import text files into my TypeScript source code. Despite spending several hours researching and attempting various methods, I have been unsuccessful in getting it to work. My journey ...

Ng5 npm is encountering an error stating 'Module './topologicalSort' could not be located.'

I encountered an issue with my Angular 5 app. Whenever I attempt to run it, I receive the following error message after running an npm start. Error: Cannot find module './topologicalSort' I suspect that this issue is related to 'webpac ...

Choose the number that is nearest to the options given in the list

I am faced with a challenge involving a list of numbers and an input form where users can enter any number, which I want to automatically convert to the closest number from my list. My list includes random numbers such as 1, 5, 10, 12, 19, 23, 100, 400, 9 ...

What is the method to verify that an Action was sent from one Action to another in NGXS?

I've been utilizing NGXS extensively throughout an application, but there are certain tasks that I still struggle to accomplish in a satisfactory manner. The documentation and other questions on this topic haven't provided the answers I seek. One ...

The issue of TypeError arising while invoking a method within TypeScript Class Inheritance

Currently, I am developing a Node.js application with TypeScript. In this project, I have a base controller class named BaseController and a derived controller called SettingController. The intention is for the SettingController to utilize methods from the ...

Angular 2 Express failing to trigger ngOnInit method

I'm having some trouble with Angular services. I used the default code from "Angular.io" to make service calls, but for some reason the ngOninit method isn't getting called. I've implemented the component from OnInit and added @Injectable to ...

How can we strengthen the type checking when defining the sorting function for json properties?

When dealing with a json structure from a service that contains .attributes json values, I often find myself needing to sort either by id from the DTO or by several attributes from the IContactsAttributes. The microservice returns this specific structure: ...

Is there a way for me to bypass adding the label if it already exists in my state, but still include the new value?

I am currently facing an issue with a dropdown select field where I can choose various attribute values. The problem arises when attempting to save the selected data in the state, as the label appears twice and I only require it once. My goal is to exclude ...

Making multiple http.get requests in Angular

Is there a way to execute only one http request but subscribe multiple times to the service? The documentation indicates that they are being called multiple times: const req = http.get<Heroes>('/api/heroes'); // 0 requests made - .subscri ...

Several different forms are present on a single page, and the goal is to submit all of the data at

Looking for assistance with combining Twitter and Google data entry at once. Here's the code I've developed: Please guide me on how to submit Twitter and Google details together. <html> <head> <script type="text/javascript">< ...

Having trouble with clearInterval in my Angular code

After all files have finished running, the array this.currentlyRunning is emptied and its length becomes zero. if(numberOfFiles === 0) { clearInterval(this.repeat); } I conducted a test using console.log and found that even though ...

What is the best way to display the strings stored in an arraylist?

I have been working on a program to read a file line by line and store the lines as arrays of strings in an ArrayList. However, when I try to print the contents of the ArrayList, it only shows the memory addresses of the string arrays instead of their actu ...

Error: Attempting to initiate a backward navigation action while already in the process. Utilizing Natiescript

I encountered an issue with the routing code in my Nativescript app. Here is the code snippet: const routes: Routes = [ { path: 'home', component: HomeComponent, canActivate: [AuthGuard], children: [ {path: 'fp&apos ...

Troubleshooting problem with the ng2-dragula drop container

Continuation of the inquiry from the discussion on ng2-dragula setOptions and drop version problem. My current workaround involves using a placeholder to address the issue of an empty container. I suspect that the approach I am currently employing, such a ...

Retrieving a specific variable from a cookie value that is stored within a JSON array

Is there a way to pass a single variable from a JSON array stored in the qookie file value to JavaScript? The qookie code looks like this: <?php $cookie_key = 'count'; CookieManager::store($cookie_key, json_encode(array( 'SameSite&ap ...

Steps for customizing the default properties of a material ui component

Is there a way to change the style properties listed on the main element? height: 0.01em; display: flex; max-height: 2em; align-items: center; white-space: nowrap; } <InputAdornment position="end" > {"hello& ...