What is the best method for showcasing organized data with select and optgroup in Angular?

Searching for a way to create a grouped dropdown select using Angular? In this case, the group is based on the make property.

const cars = [{
        make: "audi",
        model: "r8",
        year: "2012"
    },
    {
        make: "audi",
        model: "rs5",
        year: "2013"
    },
    {
        make: "ford",
        model: "mustang",
        year: "2012"
    },
    {
        make: "ford",
        model: "fusion",
        year: "2015"
    },
    {
        make: "kia",
        model: "optima",
        year: "2012"
    }
];

Expecting the dropdown select options to be grouped as follows:

audi
- r8
- rs5
ford
- mustang
- fusion
kia
- optima

Contemplating whether to transform the object before or explore other alternatives. Considered this approach: https://medium.com/@edisondevadoss/javascript-group-an-array-of-objects-by-key-afc85c35d07e

Alternatively, stumbled upon this solution: https://stackblitz.com/edit/angular-optgroup. However, note that the object structure differs.

Answer №1

If you want to display the data in a certain way, it's best to transform the object beforehand. This approach is also suggested in a similar medium article.

Looking at the stackblitz example, it's clear that the main name is key to grouping the data.

By transforming the data, you can have ngFor display group1, its opt-groups, group2, and their children sequentially. This method makes the most sense in my opinion.

UPDATED

In your stackblitz example (the one shared above), the code would look something like this:

https://i.sstatic.net/kGGuf.png

<select name="cars" id="cars">
  <optgroup *ngFor="let item of optGroups" label="{{item.name}}" >
    <option *ngFor="let sub of item.data" value="{{sub.value}}"> 
      {{sub.text}} 
    </option>
  </optgroup>
</select>

Utilizing ngFor on optgroup and option elements.

You can obtain the transformed response with this snippet:

let group = this.cars.reduce((r, a) => {
  console.log("a", a);
  console.log('r', r);
  r[a.make] = [...r[a.make] || [], a];
  return r;
}, []);

This will give you the desired transformed response - an Array of makes, each containing a number of items.

Refer to the image below where I have already implemented this approach. You can then use ngFor as described above.

https://i.sstatic.net/mEEzM.png

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

Error: The lockfile and package.json file are not synchronized when running npm

Having a problem with NPM where the package-lock and package.json files are out of sync. Tried deleting node_modules, running npm install, but issue persists. Any suggestions? Error: npm ci can only install packages when package.json and package-lock.json ...

Tips for resolving package conflicts while integrating Wagmi View into a React/Typescript application

I am facing an issue while attempting to incorporate wagmi and viem packages into my project. Currently, my project utilizes the react-scripts package with the latest version being 5.0.1, and Typescript is operating on version 4.9.5. However, upon trying ...

Expanding unfamiliar categories

Currently, I am working with Gutenberg blocks in a headless manner. Each Gutenberg block is defined by the following structure: type Block = { name: string; className?: string; key?: string | number; clientId: string; innerBlocks: Block ...

What could be causing the TypeScript class property to be undefined?

Below is the code snippet I am working with: class FeedbackController { public homePage(req, res){ this.test(); res.send('Welcome to feedback service'); } private test(){ console.log('test called'); } } export de ...

Tips for adjusting the dimensions of a child element to match its parent in Angular 12 with Typescript

I have included the child component in the parent component and I am displaying that child component within a col-md-8. What I want to achieve is to highlight a specific div in the child component with additional text, making it equal in size to the parent ...

Introduce AngularJS version 2 for better web development

I'm facing an issue with using provide in Bootstrap, and here's my code snippet: import { NgModule, provide } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from &apo ...

Having trouble determining whether a modal is currently open in an Angular application?

Greetings! I am currently working on a web application using Angular. Below is the code I have for opening a modal popup: this.formResetToggle = false; setTimeout(() => { this.formResetToggle = true; this.editorModal.s ...

Ways to retrieve the quantity of a particular value within an object using TypeScript

I'm inquiring about how to retrieve the number of a specific value within an object using TypeScript. Here is the structure of the object: obj : TestObject = { name: "test", street: "test" subobj1: { status: warning, time: ...

Transferring information between components within AngularJS

export class AppComponent { title = 'shopping-cart'; ngOnInit() { } images = [ { title: 'At the beach', url: 'https://images.unsplash.com/photo-1507525428034-b723cf961d3e?ixlib=rb-4.0.3&ixid=MnwxMjA ...

Discovering the number of items that have been filtered in isotope-layout using React and Typescript

Currently, I am utilizing the isotope-layout library within a React (Typescript) project. Although I have successfully implemented filtering on my page, I am unsure of how to retrieve the count of the filtered items. Upon loading the page, Isotope is init ...

The filter() and some() functions are not producing the anticipated output

Currently, I am in the process of developing a filtering mechanism to sift through a dataset obtained from an API. The array that requires filtering contains objects with various parameters, but my aim is to filter based only on specific parameters. For ...

The ngOnChanges lifecycle hook is triggered only once upon initial rendering

While working with @Input() data coming from the parent component, I am utilizing ngOnChanges to detect any changes. However, it seems that the method only triggers once. Even though the current value is updated, the previous value remains undefined. Below ...

Transferring information using TypeScript

My issue arises when transferring data from HTML in the following format Karbohidrat :{{karbohidrat}} <button ion-button (click)="cekHalamanMakanan('karbohidrat')">View carbohydrate foods</button> <br> Then, I retrieve the kar ...

I am interested in incorporating a personalized class into the Kendo UI for Angular TabStrip

<kendo-tabstrip (tabSelect)="onTabSelect($event)"> <kendo-tabstrip-tab title="Paris" [selected]="true"> <ng-template kendoTabContent> <div class="content"> ...

Create a custom sorting pipe in Angular 10 that allows for a specific value hierarchy to be passed, without adhering

I am attempting to sort a list of form objects in angular 10 using a custom pipe. The goal is to order them based on a specific property with the following priority: [{VALID: 1}, {INVALID: 2}, {DISABLED: 3}]. I have defined this order as an argument for th ...

Utilizing Angular 11's HostListener to capture click events and retrieve the value of an object

Using the HostListener directive, I am listening for the click event on elements of the DOM. @HostListener('click', ['$event.target']) onClick(e) { console.log("event", e) } Upon clicking a button tag, the "e" object contains the fol ...

Clicking on an element- how can I find the nearest element?

Encountering an issue with my next js app where I am attempting to assign a class to an element upon clicking a button. The problem arises when trying to access the next div using the following code snippet: console.log(e.target.closest('.request_quot ...

What could be causing the type errors I am encountering while trying to resolve this Promise within a generic function?

I am attempting to implement additional types within this WebSocket protocol: type Action = { action: "change-or-create-state"; response: string; } | { action: "get-state"; response: string | null; }; /** * map an action to its response ...

Unable to invoke an external function from bolt Response Handler Callback

I am facing an issue where I am unable to call my Update method from the bolt responseHandler. Can someone please help me with this problem? Using Angular 9: Error: core.js:1673 ERROR TypeError: this.updatePaymentInfo is not a function at Object.resp ...