How to prevent value overwriting when adding dynamic fields in Angular 7?

In my current project using Angular, I am tasked with setting up configuration using 4 specific fields:

  • Department Name (select option)
  • Service Name (select option)
  • Status (text input)
  • Level (text input).

I need to be able to add multiple sets of these fields and create a JSON structure.

  • The values for 'Department Name' and 'Service Name' are retrieved through API calls.
  • The options for 'Service Name' depend on the selected 'Department Name'.

Although I have successfully implemented the dynamic addition of fields, I encounter an issue where selecting a Department Name causes the corresponding Service Name to overwrite all previously selected 'Service Name' fields.

Below is a snippet from my component.html file:

//mapFormGroup returns FormArray for given set of fields
<div *ngFor="let map of mapFormGroup.controls; let i = index;">
    <div [formGroupName]="i" class="row">
        <label>Department Name</label>
        // getServices fetches all services for selected department
        <select class="form-control" formControlName="deptId" type="text" (change)="getServices($event.target.value)">
            // deptList contains list of all departments
            <option *ngFor="let dept of deptList" [value]="dept.id">{{dept.name}}</option>
        </select>
        <label>Service Name</label>
        <select class="form-control" formControlName="serviceName" type="text">
            // serviceList contains list of all services for given department
            <option *ngFor="let service of serviceList" [value]="service.wfName">{{service.description}}</option>
        </select>
    </div>
</div>

I need to ensure that each Department corresponds correctly to its respective Service Name field without any overwriting occurring. Please assist in resolving this issue.

Answer №1

data: Service[]; // define a class for service or use an empty array;
ngOnInit(){
 this.data = [];
  this.ServiceService.getServices().subscribe( response => {
    response.forEach(item => {
      console.log(item);
      const newService = new  Service(
      item.ServiceId, item.Name); // constructor function or update accordingly 
      this.data.push(newService);
  });
}
filterServices(value){
this.filteredServices = this.data.filter(obj => 
             String(obj.DepartmentName).toUpperCase() === String(value));
}

Answer №2

I managed to overcome the challenge by implementing the following modification:

Within my component.html:

// The mapFormGroup function returns a FormArray based on the provided fields
<div *ngFor="let map of mapFormGroup.controls; let i = index;">
    <div [formGroupName]="i" class="row">
        <label>Department Name</label>
        // getServices retrieves all services for the selected department
        <select class="form-control" formControlName="deptId" type="text" (change)="getServices($event.target.value,**i**)">
            // deptList contains a list of all departments
            <option *ngFor="let dept of deptList" [value]="dept.id">{{ dept.name }}</option>
        </select>
        <label>Service Name</label>
        <select class="form-control" formControlName="serviceName" type="text">
            // serviceList includes all services for the specified department
            <option *ngFor="let service of **fnServiceList(i)**" [value]="service.wfName">{{ service.description }}</option>
        </select>
    </div>
</div>

In my component.ts:

// Added a new function to retrieve the array element at the current index 
**fnServiceList(row) {
    return this.serviceList[row];
}**

// Updated the function parameters to use the row index in assigning values to the array 
getServices = function (dept, **row**) {
    // Retrieve services for the specified department and store them in "services"
    this.serviceList**[row]** = services;
    // Replaced: "this.serviceList = services;"
}

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

Tips for bringing in a text file within a NodeJS application using TypeScript and ts-node during development

I am currently developing a NodeJS/Express application using TypeScript, Nodemon, and ts-node. Within this project, there is a .txt file that contains lengthy text. My goal is to read the contents of this file and simply log it to the console in developmen ...

Determining the parameter type of an overloaded callback: A comprehensive guide

I am currently working on creating a type-safe callback function in TypeScript with a Node.js style. My goal is to define the err parameter as an Error if it exists, or the data parameter as T if not. When I utilize the following code: export interface S ...

Coordinating Angular to communicate with Node.js to send and receive data

I am currently working on a project using express.js, but I would like to integrate angular into the project to create a single page application. The website currently refreshes the entire content from the server whenever a link is clicked, which seems ine ...

When using a function as a prop in a React component with Typescript generics, the type of the argument becomes unknown

React version 15 or 18. Typescript version 4.9.5. When only providing the argument for getData without using it, a generic check error occurs; The first MyComponent is correct as the argument of getData is empty; The second MyComponent is incorrect as t ...

When running the command `npm start`, an error message is generated

Hey everyone, I've been trying to learn some basic AngularJS 2.0 skills through a tutorial. Unfortunately, when I tried running the command npm run start, it didn't work as expected. I'm currently using Git Bash on Windows 10 OS. If you hav ...

TypeError: Unable to find TextEncoder in mongoose and jest when using TypeScript

Currently, I am working on a project using Node 14 along with Express v4.16.3 and Typescript (v4.7.4). Recently, I added Mongoose (v6.5.2) to the project, and while the logic code seems fine, most of the tests executed by Jest (v26.4.2) are failing with th ...

When I declare a second service in the constructor, my modal service no longer opens as expected

Recently, I came across this login method in Angular: email: string = ""; password: string = ""; login() { const credentials = { email: this.email, password: this.password }; this.userService.login(credential ...

Angular 9's localization feature is not functioning properly when using the configuration flag --configuration=de

When I utilize $localize from "@angular/localize/" with "ng serve --configuration=de", the result that I obtain is shown in the following image: https://i.sstatic.net/oxusb.png Everything functions perfectly when executing the project with just "ng serve ...

Tips for effortlessly incorporating a new chip while maintaining a neat arrangement and ensuring button alignment

I am looking to enhance my website by adding chips with new tags in a neatly organized manner. Specifically, I want each new chip to be positioned next to the previous one and have the add-button shift to the right side, always staying in front of the last ...

Encountering issues with FlexLayoutModule in Angular 11

After adding the FlexLayoutModule and including it in my project, I encountered the following error: Error: node_modules/@angular/flex-layout/typings/module.d.ts:16:22 - error NG6002: Appears in the NgModule.imports of AppModule, but could not be resolved ...

Versatile Typescript options

Is it possible to enforce a value to be within a list using TypeScript with enums? Can this be achieved with TypeScript type definitions? enum Friend { JOHN, SALLY, PAUL, } type MyFriends = { friends: Friend[], bestFriend: <> //How ca ...

Utilizing Async and await for transferring data between components

I currently have 2 components and 1 service file. The **Component** is where I need the response to be displayed. My goal is to call a function from the Master component in Component 1 and receive the response back in the Master component. My concern lies ...

Developing a separate NPM package for a portion of the app causes an increase in the total app size

Our projects utilize create-react-app and Typescript, resulting in the emergence of a collection of commonly used React components. To enhance maintenance and reusability, we decided to extract these components into their own NPM package named PackageA. Su ...

Trigger the rowContextMenu in Tabulator Table by clicking a Button

Is there a way to add a button at the end of a table that, when clicked, opens a rowContextMenu below the button? Additionally, can the rowContextMenu pop up when right-clicking anywhere on the row? I have attempted some solutions without success. Here is ...

What method can I utilize to display a value that deviates from the one stored in the backend using Record?

Here is the HTML snippet that I am working with: <drop-down-list [name]="MeetingTool.Type" [options]="options$" [isRequired]="false" class="input-width" ...

What is the best way to handle the completion of an HTTP request in Angular 8?

This is the service provided. existWayBillByRsBillNumber(billNumber: string){ return this.http.get<boolean>(this.baseUrl + 'Common/ExistWayBillByRsBillNumber/'+billNumber); } This is how the service call is made. this.commonServic ...

When using *ngFor with AngularFireList, an error is thrown indicating an invalid

I'm struggling to grasp why I'm getting an invalid pipe argument error with *ngFor when using async. Without async, I'm told that NgFor only supports binding to iterables like Arrays. Oddly enough, the same code works fine on another page bu ...

Is it possible to pass a parameter to an NGXS action that is not the Payload?

I am working on implementing an Ngxs action that includes a parameter in addition to the payload. This parameter is used to determine whether or not a notification should be sent. @Action(UpdateUser) async UpdateUser( ctx: StateContext<ProfileStat ...

Add a npm module without type definitions

I am currently utilizing Typescript version 2.1 and facing an issue with installing an npm package called 'reactable' that lacks typings. When attempting to import the package using import * as Reactable from 'reactable', Typescript di ...

Is there a way to enforce a mandatory lambda argument?

I am trying to pass a lambda into a function, but I need the lambda to have only one argument. TypeScript correctly generates an error if I provide two parameters to the lambda, however it does not raise any issues if I leave out any arguments altogether ...