Develop an object's attribute using form in the Angular 5 framework

I am looking to create an object for a location that includes two parameters. While I can easily create an array of strings using FormGroup, I am unsure of how to create an object with two parameters nested inside it. Below is the code snippet I currently have:

bucketForm: FormGroup; // declared at the top of the class component

ngOnInit() {
    this.initForm();
  }

private initForm() {
    let bucketName = '';
    let bucketLocation = {};
    let bucketObjects = new FormArray([]);

    this.bucketForm = new FormGroup({
      'name': new FormControl(bucketName, Validators.required),
      'location': // Here I want to create a Location Object with two parameters {id: 'Some random number', name: 'New York'},
      'bucketObjects': bucketObjects
    });
    console.log(this.bucketForm);
  }

To capture input values from the .html file of the component, I have a simple form setup below:

<form [formGroup]="bucketForm" (ngSubmit)="onSubmit()">
    <div class="row">
      <div class="col-md-6">
        <label for="name">Bucket Name*</label>
        <input
          type="text"
          class="form-control"
          id="name"
          formControlName="name">
      </div>
      <div class="col-md-6">
        <label for="bucketLocation">Bucket Location*</label>
        <select
          class="custom-select d-block w-100"
          id="bucketLocation"
          formControlName="location">
          <option
            *ngFor="let locationEl of locations" [value]="locationEl.name">{{ locationEl.name }}
          </option>
        </select>
      </div>
    </div>
    <hr>
    <button
      type="submit"
      class="btn btn-primary"
      [disabled]="!bucketForm.valid">Create Bucket
    </button>
    <button class="btn btn-danger">Cancel</button>
  </form>

This is my current bucket model structure which includes an array of buckets:

Bucket {
    id: "BucketExample", // string
    name: "BucketExample", // string
    location: Location, // object { id: string, name: string }
    bucketObjects: Array(0)
}

Screenshot for reference:

Answer №1

When setting a value for one of the properties of a form, it's important to remember that you need to use a FormGroup instead of just a FormControl.

A FormGroup allows you to have an object as a property, and you can even nest FormGroups within each other. In your case, the bucketForm should be defined like this:

this.bucketForm = new FormGroup({
  'name': new FormControl(bucketName, Validators.required),
  'location': new FormGroup({
      id: new FormControl(Math.random()),
      name: new FormControl('')
  }),
  'bucketObjects': bucketObjects
});

To set the value of a select control as an object rather than primitive values, you'll need to utilize the ngValue directive.

Since we are dealing with setting an object directly, make sure to provide the form control object as input, instead of using the formControlName attribute. For example,

[formControl]="bucketForm.get('location')"

Your HTML code should resemble something like this:

<select class="custom-select d-block w-100" id="bucketLocation" [formControl]="bucketForm.get('location')">
   <option
     *ngFor="let locationEl of locations" [ngValue]="locationEl">{{ locationEl.name }}
   </option>
</select>

Check out the Stackblitz demo here!

Answer №2

Below is the provided solution:

For the HTML file:

<select class="custom-select d-block w-100"
                id="bucketLocation"
                formControlName="location"
                ngModel>
          <option value="" disabled>Choose...</option>
          <option
            *ngFor="let locationEl of locations" [ngValue]="locationEl">{{ locationEl.name }}
          </option>
        </select>

In the TypeScript file:

private initForm() {
    let bucketName = '';
    let bucketLocation = {};
    let bucketObjects = new FormArray([]);

    this.bucketForm = new FormGroup({
      'name': new FormControl(bucketName, Validators.required),
      'location': new FormControl(bucketLocation, Validators.required),
      'bucketObjects': bucketObjects
    });

}

The solution was sourced from examples found at: Angular API documentation

Credit goes to @cyberpirate92 as well.

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

Creating a Form with a Custom Format in AngularJS

Just starting out with AngularJS and currently working with ACTIVITI. I'm looking to create a form in a specific structure where each response follows this format: { "taskId" : "5", "properties" : [ { "id" : "room", ...

Tips for creating an effective unit test using Jest for this specific controller

I'm currently grappling with the task of unit testing my Controller in an express app, but I seem to be stuck. Here are the code files I've been working with: // CreateUserController.ts import { Request, Response } from "express"; impor ...

Guide on utilizing the useContext hook in React/Next.js while incorporating TypeScript

As I embark on my journey in the world of TypeScript, I find myself working on a new project in Next.js using TypeScript. My goal is to incorporate authentication functionality into this project by utilizing createContext. Coming from a background in JavaS ...

What is the method for incorporating a variable into a fragment when combining schemas using Apollo GraphQL?

In my current project, I am working on integrating multiple remote schemas within a gateway service and expanding types from these schemas. To accomplish this, I am utilizing the `mergeSchemas` function from `graphql-tools`. This allows me to specify neces ...

"Exploring the dynamic duo: Algolia integration with Angular

I've been following a tutorial on implementing instantsearchjs in my website, which can be found here. Everything is set up correctly and I can query for results in .JSON format from my website. However, I'm having trouble figuring out how to r ...

Is there a way to use an Angular interceptor to intercept and modify static files like .html files? I would like to change the lang

While researching Angular intercepting, I stumbled upon this helpful documentation: here. My goal is to intercept HTML using an Angular interceptor in order to modify the HTML file before it's displayed in the browser. Trying to accomplish this on the ...

How can models be aggregated in SQL by connecting them through other models?

I am working with a backend express API that utilizes sequelize. In my sequelize models, a Citizen is linked to a Street, which in turn is associated with a Town, and the Town is connected to a State. I can easily count the citizens on a specific Street by ...

Using TypeScript's `extend` keyword triggers an ESLint error when attempting to extend a generic type

I am dealing with numerous models that include additional meta data, which led me to create a generic type for appending them to the models when necessary: type WithMeta<T> = T extends Meta; However, I encountered an error stating: Parsing error: &a ...

How to display a modal within a router-link in Vue 3?

Below are buttons with router-links. However, I only want the calculator button to open a modal. When I execute the code provided, all buttons trigger the modal instead of just the calculator button. Output: Router-link Code: <div class="contai ...

Regular expression for the validation of emails using a delimiter

Can someone help me create a regex expression for emails? This is what I have so far: \S+@\S+\.\S+ I want to repeat this X times with a ; separator. Any ideas on how to achieve this? For example, the pattern should allow strings like: ...

Find strings that contain some text other than Angular expressions using Regex

I recently discovered a need to identify strings in our projects that are not AngularJS expressions due to expanding into multiple languages. This includes any string that is not completely enclosed in curly braces. My goal is to create a regex pattern th ...

Comparing tsconfig.json and tsconfig.build.json: what sets them apart?

Guides like those found at 1 and 2 often recommend having two separate files - tsconfig.json and tsconfig.build.json - at the root level of an NPM monorepo for TypeScript projects. What are the distinctions between these files? Is it possible to consolida ...

Show the Form Data in a Stylish Bootstrap Popup

Our website's homepage features a basic form that sends its results to a page named Results.aspx. Instead of displaying the form results on the same page, I want them to appear in a new modal window. How can this be done? Just to summarize, the form ...

Leveraging an AngularJS service within Angular framework

I am trying to incorporate an AngularJS service into my Angular project. Below is my main.ts file: import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; import {AppModule} from './app/app.module'; import {UpgradeMo ...

transitioning from angular cli version 1.7 to version 12

Looking for a detailed guide on upgrading from version 1.7 to the latest Angular version (12/11)? I currently have an app running on version 1.7 and couldn't find a step-by-step process here: upgrading angular Would it be safe to assume that the upgr ...

formBuilder does not exist as a function

Description: Using the Form Builder library for react based on provided documentation, I successfully implemented a custom fields feature in a previous project. This project utilized simple JavaScript with a .js extension and achieved the desired result. ...

"Utilizing Typescript and React to set a property's value based on another prop: A step-by

Is there a way to create a dynamic prop type in React? I have an Alert component with various actions, such as clicking on different components like Button or Link. I am looking for a solution like this: <Alert actions={[{ component: Link, props: { /* ...

What is the significance of TypeScript's dual generic typing feature?

defineListenerShape< EventName extends string, EventData extends { [key in EventName]: unknown; } > = <E extends EventName>(data: EventData[E]) => void; enum EventName { Click = 'click', Hover = 'hover' ...

What is the most effective method for displaying indicators for in-flight requests in rxjs without causing side effects?

What is the best way to display a loading indicator for an ongoing request using RXJS (along with Angular2+) without causing side effects in the pipe() function? I've brainstormed some options. Is there a recommended approach or a better alternative? ...

How do I manage two components on the same routing level in Angular with query parameters?

I am working with Angular and have two components placed at the same level of routing, both in the root directory. { path: '', component: HomeComponent }, { path: '', component: SearchComponent }, My challenge is to mak ...