Include a control within a form based on the Observable response

I am looking to enhance my form by adding a control of array type, but I need to wait for the return of an Observable before mapping the values and integrating them into the form.

The issue with the current code is that it inserts an empty array control even if there is no observable data available.

My goal is to ensure that all observable data has been returned before adding the control. I want to retrieve the last value within subscribe and then insert the control based on the number of users returned.

In my HTML, I want to display checkboxes with the names of users, indicating whether they are tagged or not. This information will be stored in the array along with the user's ID and a boolean value.

component.ts

    users$ = this._store.select(usersSelectors.getUsers);

    this.myForm = this._formBuilder.group({
        // .... controls
    });

    this.users$.pipe(
        filter((data) => !!data),
        map(users => this._formBuilder.array(users.map(() => new FormControl(false))))
    ).subscribe(usersArray => 
        this.myForm.addControl('users', usersArray)
    );

component.html

<div class="col-md-3">
  <label for="users">Users</label>
  <div id="users" class="row">
    <div class="checkbox" class="col-sm-4"
      formArrayName="users"
      *ngFor="let item of myForm.get('users').controls; let i = index" >
      <label class="checkbox-inline">
        <input type="checkbox" [formControlName]="i"> {{ users$[i].name }}
      </label>
    </div>

Return from users$:

0: {subscriber: false, avatar: "", name: "Paul", id: "eXrrdOfmUGYHFIOVCWjBnAO7PZ52" …}
1: {subscriber: true, avatar: "", name: "Will", id: "NoQMVGnCA6VPc42ksIa6AqZZNWL2" …}

When marking the user, the 'users' control should look like this:

users: [
{eXrrdOfmUGYHFIOVCWjBnAO7PZ52: false}
{NoQMVGnCA6VPc42ksIa6AqZZNWL2: true}
]

Answer №1

To start, you can initialize the form and dynamically add controls based on the Observable value. Here's an example of how this can be achieved:

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { FormBuilder, FormGroup, FormArray } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  users;
  form: FormGroup;

  constructor(
    private http: HttpClient,
    private fb: FormBuilder
  ) {}

  get usersForm() {
    return (<FormArray>this.form.get('users')).controls;
  }

  ngOnInit() {

    this.form = this.fb.group({
      users: this.fb.array([])
    });

    this.http.get('https://jsonplaceholder.typicode.com/users')
      .subscribe(users => {
        this.users = users;
        this.users.forEach(user => {
          if(typeof(user) == typeof(true)) this.usersForm.push(this.fb.control([user.tagged]));
        });
        console.log('Users Form: ', this.usersForm);
      });
  }
}

Feel free to explore a Demo on StackBlitz showcasing the implementation.

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

Using the expect statement within a Protractor if-else block

My script involves an if-else condition to compare expected and actual values. If they do not match, it should go to the else block and print "StepFailed". However, it always executes the if block and the output is "step passed" even when expected does not ...

The query fails to retrieve results for the specified date and the beginning of the month

I have encountered an issue with my query that is supposed to fetch values between the start and end of the month. Interestingly, when a record is entered on the first day of the month, it doesn't get returned in the query result. Only records entered ...

Unable to show the input's value

Need help in taking user input to display calculated values //html <div class="empty"> <h5> Enter Empty Seats </h5> <ion-item> <ion-input placeholder="Enter Number of Empties.." type="number" name="emptySeats" [( ...

Leveraging ZOD's discriminatedUnion() method to differentiate among three different forms

ValidationSchema = z.object({ AuthenticationBlock: z.object({ ChoiceOfForm: z.enum() DataBlock: z.discriminatedUnion(ChoiceOfForm, [ z.object({ ChoiceOfForm = 1, empty fields}) //corresponds to the basic form z.object({ ChoiceOfForm = 2, just ...

Lint found an issue: The variable 'post' has been defined but is not being utilized in the code

Within my codebase, I have included the following import: import { post } from '@loopback/rest' This is how I am utilizing it in my project: export class MyClass { @post('/example/test', {}) } Unfortunately, a lint error has been de ...

Limit the covariance of properties in generic arguments

When I define a generic argument of object type with specific mandatory properties (for example, in this function it requires the object to have timestamp: string), TypeScript allows for using a more specialized attribute type as a generic argument - as sh ...

Why won't the sound play on the button with the picture?

I am currently working on a website project that requires buttons with pictures and sound. Despite my efforts, the sound feature is not functioning properly in Chrome and Firefox. I am still learning and would like to know how to toggle the sound on and of ...

Add the item to the array and then use the *ngFor directive to iterate

Whenever the addRoom button is clicked, I want to add an object to an array. The problem is that the data in my array keeps getting repeated. Please excuse any language errors in my explanation. Feel free to ask me for clarification in the comments below. ...

The 'id' property is not found within the 'Order[]' type

Encountering a perplexing issue in my HTML where it keeps showing an error claiming that the 'id' property does not exist on type Order[] despite its clear existence The error message displayed: Property 'id' does not exist on type &ap ...

Conceal the choice when aria-expand is in a deactivated state

I'm currently facing a challenge with hiding an option in mat-select only when aria-expanded is false. In the dropdown menu, I have both "Select All" and "Deselect All" options. However, when the menu is closed, it displays "Deselect All" by default ...

Unable to load the .js file within the Angular module

I am facing an issue with my Angular sidebar component that is trying to load a local script called sidebar.js. I have the following code in src\app\sidebar\sidebar.component.ts: ngAfterViewInit(): void { const s = document.createEleme ...

The latest version of Angular, Angular 16, brings along its own set of challenges

Just completed the update to version 16 of Angular and encountered the following error message: The injectable CustomMsalInterceptor inherits its constructor from MsalInterceptor, but MsalInterceptor does not have its own Angular decorator. This will resu ...

Unexpected token error in TypeScript: Syntax mistake spotted in code

Being new to Angular, I understand that mastering TypeScript is crucial for becoming a skilled Angular developer. Therefore, I created this simple program: function loge(messag){ console.log(messag); } var message:string; message = "Hi"; loge(messa ...

Error encountered during sequelize synchronization: SQL syntax issue detected near the specified number

Four Sequelize Models were created using sequelize.define();. Each model is similar but with different table names. To avoid manual creation of tables in MySQL cli, the decision was made to use sequelize.sync() in the main index.js file to allow Sequelize ...

Is there a way to program a function that can automatically trigger or refresh an HTTP POST method?

How can I create a method in a distant component that will run a POST request when a button is clicked? I believe I need to use a service in this situation. It's not necessary for it(this.qwe) to be in the constructor, it's just an example... ...

Initiating a GET request to execute an SQL query with specified parameters

Let me provide some background information. I am currently using Angular for the frontend and Express for the backend, while also learning how to effectively utilize both technologies. In my application, there is a parent component that generates a group ...

The use of throwError(error) has been phased out, however, no replacement has been introduced for the Error(HttpErrorResponse)

It seems like the use of throwError(error) is deprecated now. VS Code suggests using throwError(() => new Error('error')) instead, as new Error(...) only accepts strings. How can I replace it correctly without causing issues with my HttpErrorH ...

Having trouble with npm install on an Angular project? It seems to be failing with an ECONNREFUSED error while trying to

I am facing an issue while trying to clone one of my Angular projects. To make it work, I need to run npm install, which used to work fine in the past. However, recently I encountered the following error: npm install npm ERR! code ECONNREFUSED npm ERR! ...

Form with checkboxes in a Next.js and Typescript application

I am currently working on a project using Next.js and Typescript. I have implemented a form in this project, which is my first experience with Typescript and checkbox types. However, I am encountering difficulties in retrieving all checkbox values, adding ...

Transforming an Image URL into base64 format using Angular

I'm currently facing difficulty when attempting to convert a specified image URL into base64. In my scenario, I have a string that represents the image's path. var imgUrl = `./assets/logoEmpresas/${empresa.logoUrl}` Is there a way to directly co ...