Enhancing Angular Forms with a Dynamic Dropdown Feature

I am currently working on incorporating dynamic forms into my project, inspired by the example illustrated in this link: How to create a generic component with form control input for Angular Forms in application. I am facing challenges in loading an asynchronous list for a select control and populating a second select based on the first one.

  async loadGender() {
    return of<any>([
        { value: "", label: "Please choose", selected: true },
        { value: "0", label: "male" },
        { value: "1", label: "female" }
      ]).pipe(
      delay(2000)
    );
  }
    async loadStyle() {
    return of<any>([
        { value: "",  gender: '' , label: "X", selected: true },
        { value: "0", gender: '0',  label: "Y" },
        { value: "1", gender: '1',  label: "Z" }
      ]).pipe(
      delay(2000)
    );
  }

Answer №1

const genderData = this.loadGender().map(res => res.json());
const styleData = this.loadStyle().map(res => res.json());

Observable.forkJoin([genderData, styleData]).subscribe(data => {
  console.log('Combined observables result:', data)
});

Here is a method to merge two observables together.

Answer №2

It appears that you are utilizing reactive forms based on the link provided.

To achieve your goal, pay attention to the valueChanges observable, which triggers a new value whenever there is a change in the form control's value.

This emitted value allows us to update the options list for the second select element.

In the app.component.ts file:

export class AppComponent {
  public carsForm: FormGroup;
  public cars$: Observable<any[]>;
  public models$: Observable<any[]>;

  private carFormControl = new FormControl("");
  private modelFormControl = new FormControl("");
  private carChangeSubscription: Subscription;

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.carsForm = this.fb.group({
      car: this.carFormControl,
      model: this.modelFormControl
    });

    this.cars$ = this.getCars();

    this.carChangeSubscription = this.carFormControl.valueChanges.subscribe(
      carId => {
        this.modelFormControl.setValue("");
        this.models$ = this.getModels(+carId);
      }
    );
  }

  ngOnDestroy() {
    this.carChangeSubscription.unsubscribe();
  }

  private getCars() {
    return of([
      {
        id: 1,
        name: "MERCEDES-BENZ"
      },
      {
        id: 2,
        name: "VOLVO"
      },
      {
        id: 3,
        name: "AUDI"
      },
      {
        id: 4,
        name: "HONDA"
      }
    ]);
  }

  private getModels(carId: number) {
    return of([
      {
        id: 1,
        carId: 1,
        name: "SL55 AMG"
      },
      {
        id: 2,
        carId: 2,
        name: "C70"
      },
      {
        id: 3,
        carId: 3,
        name: "S4"
      },
      {
        id: 4,
        carId: 4,
        name: "CR-V"
      }
    ]).pipe(
      map(models => {
        return models.filter(x => x.carId === carId);
      })
    );
  }
}

For the app.component.html file:

<form [formGroup]="carsForm">
   <select formControlName="car">
    <option value="">Please select</option>
    <option *ngFor="let car of cars$ | async" [value]="car.id">
      {{car.name}}
    </option>
  </select>
  <br /><br />
  <select formControlName="model">
    <option value="">Please select</option>
    <option *ngFor="let model of models$ | async" [value]="model.id">
      {{model.name}}
    </option>
  </select>
</form>

The AsyncPipe is used to subscribe to the two data observables.

We ensure to unsubscribe from the valueChanges observable when the component is destroyed.

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 difficulty applying a border to the popup modal

Currently, I am utilizing a Popup modal component provided by the reactjs-popup library. export default () => ( <Popup trigger={<button className="button"> Guide </button>} modal nested > {(close: any) =&g ...

Is there a way to bypass the requirement of specifying event: MouseEvent when using methods with Vue.extend() and TypeScript?

Take a look at this simple example import Vue from "vue"; export default Vue.extend({ props: { text: String, }, methods: { click() { console.log(this.text); // Property 'text' does not exist on type 'Vue'. ...

Ensuring an integer value is selected in Angular

<form [formGroup]="form"> <select name="area_id" formControlName="area_id"> <option value="1">Value A</option> <option value="2">Value B</option> <option value="3">Value C</option> ...

Learn about Angular8's prototype inheritance when working with the Date object

In my search for a way to extend the Date prototype in Angular (Typescript), I stumbled upon a solution on GitHub that has proven to be effective. date.extensions.ts // DATE EXTENSIONS // ================ declare global { interface Date { addDa ...

An issue has arisen: It seems that properties of null cannot be accessed, particularly the 'toISOString' property

After upgrading the dependencies in my package.json to their latest versions, I encountered an error while accessing a page that calls this data. Given that the dependencies were outdated by at least 2 years or more, I suspect the issue lies with the updat ...

How can I prevent node_module from being included when using the include directive in tsconfig.json?

Many developers are excluding the node_modules folder in their tsconfig.json. I, on the other hand, am using the include directive with specific folder patterns. Do I really need to exclude node_modules? And what about third-party libraries that aren' ...

Angular HttpClient request fails to initiate

Overview: A button click on a form triggers the methodForm within the component. methodForm then calls methodService in the service layer. methodService is supposed to make an HTTP POST request. Problem: The HTTP POST request is not being made. However, me ...

Is it possible to navigate to a particular step during an Angular IntroJS event?

Whenever I attempt to navigate to a specific step from within the IntroJS onexit event, it seems to cause confusion and display the incorrect step along with the highlighted element. I have defined my steps using JSON, with a total of 8 steps: [{ elem ...

Allow exclusively certain type to pass through the function

Is it possible to receive an error message from the function in the following example? I have included comments at a relevant spot in the code below: interface Pos { x: number, y: number, } function doSome(pos: Pos) { return pos.x + pos.y } let p ...

What is the best way to decouple api and async request logic from React components while incorporating Recoil?

Currently, I find myself inserting my request/api logic directly into my components because I often need to set state based on the response from the backend. On my settings page, I have a function that saves the settings to recoil after the user clicks sa ...

Angular 6: TypeError - The function you are trying to use is not recognized as a valid function, even though it should be

I'm currently facing a puzzling issue where I'm encountering the ERROR TypeError: "_this.device.addKeysToObj is not a function". Despite having implemented the function, I can't figure out why it's not functioning properly or callable. ...

Guide to implementing ion-toggle for notifications with Ionic 2 and Angular 2

Currently, I am using a toggle icon to set the notification as active or inactive. The response is obtained from a GET call. In the GET call, the notification value is either 0 or 1, but in my TypeScript file, I am using noteValue as boolean, which means w ...

What is the best way to tally up the occurrences of a specific class within an Angular application?

After reviewing the resources provided below on impure and pure pipes in Angular applications: What is impure pipe in Angular? I have been curious about inspecting the instances created by an Angular application firsthand, although I am uncertain if thi ...

Angular Gitlab CI/CD Pipeline Configuration with .gitlab-ci.yml

I'm new to continuous deployment with Gitlab and am trying to set up a pipeline for Angular. Everything is working smoothly except for the fact that I am unable to copy the dist folder from one location to another using the commands mentioned below. ...

Leveraging the expand function for pagination through recursive invocations

I am currently working on retrieving data from a third party API that necessitates manual management of paging by keeping track of the number of records retrieved versus the total number of records available. In attempting to handle this, I experimented w ...

Is it possible to use the conditional (ternary) operator within the [ngClass] directive in Angular2 while also including multiple class conditions?

Would it be possible to combine multiple conditions with ternary operator, like in the following example that currently doesn't work? <div [ngClass]="{'checked': isChecked, 'disabled': isDisabled, isEmpty ? 'empty-class&ap ...

Angular 2 Lazy Loading and Global Singletons in Apps - Custom HTTP Class Issue Unresolved

I am implementing Angular 2 Router Lazy Loading in order to improve initial load time. Within my application, I have customized the default Http service of Angular to show a loader whenever an http request is made, which then gets hidden upon completion. ...

Creating a custom utility type in TypeScript for serializing an array of objects: What you need to know

Imagine I have the following specified object: type Test = { date: Date num: number str: string } In this object, there is a Date type that needs to be converted into a string ("serialized"). To achieve this, I came up with the concept of a Generic ...

When it comes to field validations, should they be implemented on the frontend or backend? Which

In the process of creating a login and registration form, I am integrating Angular 6 for the frontend and NodeJs for the backend. I would like to gather opinions on whether it is preferable to handle field validation in Angular or in Node? ...

managing various states in React with the help of useReducer

Currently, I am working on a registration form that allows users to switch between displaying and concealing passwords in the input fields. The setup includes two password input sections - one for creating a password and another for re-entering it. Each in ...