Steps for modifying and refreshing the dynamically included input data

Situation:

The example below shows a file named contacts in JSON format:

[
   {
     "name": "Ailis Wyld",
     "addresses": [
        {
            "addressType": "Business",
            "city": "Lansing",
            "postalCode": "48930"
        },
        {
            "addressType": "Home",
            "city": "Young America",
            "postalCode": "55573"
        }
     ]
  },
  {
    "name": "Aksel",
    "addresses": [
        {
            "addressType": "Business",
            "city": "Battle Creek",
            "postalCode": "49018"
        },
        {
            "addressType": "Home",
            "city": "Memphis",
            "postalCode": "38131"
        }
    ]
   },
   {
     "name": "Dearan",
     "addresses": [
        {
            "addressType": "Other",
            "city": "Minneapolis",
            "postalCode": "55417"
        },
        {
            "addressType": "Other",
            "city": "Sacramento",
            "postalCode": "95833"
        }
    ]
   }

]

I have a display for the name and address of each contact, like shown here:

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

Desired Outcome:

  • For multiple addresses displayed, clicking on a specific address (e.g., addressType: Home) should allow me to edit that address by showing its values (addressType, city, postalCode) in input fields as depicted here: https://i.sstatic.net/Tt4S2.png

This would enable me to make edits and update that particular address.

  • Additionally, I should be able to add a new address using those input fields.

Here is a link to my stackblitz DEMO

Answer №1

check out this live demo

Here are the modifications I made:

  • Switch between Update mode for selected addresses and Add mode for new ones
  • Include form data in the contacts array based on the selected index
  • Update the address with edited information once saved

  selectAddr(addr) {
    this.newAttribute.addressType = addr.addressType;
    this.newAttribute.postalCode = addr.postalCode;
    this.newAttribute.city = addr.city;

    this.selectedAddr = addr;
  }

  saveAddress(index, form: FormGroup) {
    const mode: 'update' | 'add' = this.selectedAddr ? 'update' : 'add';

    if (mode === 'add') {
      this.contacts[index].addresses.push({ ...this.newAttribute });
    } else if (mode === 'update') {
      Object.assign(this.selectedAddr, this.newAttribute);
    }

    // reset
    this.selectedAddr = undefined;
    form.reset();
  }
<div class="main" *ngFor="let contact of contacts;let i = index">

<form [formGroup]="addForm" #myForm>

  <p>Name: {{contact.name}}</p>
  <br>
<!--Address section-->
      <div  class="address-sec">
        <p id="addr">Addresses</p>
        <br>
        <table style="width:100%" *ngFor="let addr of contact.addresses">
            <tr>
                <td>
                  <div id="field-type">
                      <mat-chip-list>
                        <mat-chip color="primary" (click)="selectAddr(addr)" selected>{{addr.addressType}}</mat-chip>
                      </mat-chip-list>
                  </div>
                </td>
                <td>
                    <div class="field-data">
                   {{addr.city}}-{{addr.postalCode}}
                </div>
                  </td>
                <td>
                    <div class="field-data">
                    <b>Delete</b>
                   </div>
                </td>
            </tr>
          </table>
        <hr>
        <br>
      </div>
  <br>
  <!--Address Section-->

  <mat-form-field>
    <mat-select formControlName="addressType" placeholder="Type" [(ngModel)]="newAttribute.addressType">
        <mat-option *ngFor="let addressType of addresstypes" [value]="addressType.value">
            {{addressType.viewValue}}
        </mat-option>
    </mat-select>
</mat-form-field>

<br>
     
<mat-form-field >
    <input matInput formControlName="postalCode"  [(ngModel)]="newAttribute.postalCode"  placeholder="Postal Code" >
</mat-form-field>
<br>
<mat-form-field >
    <input matInput formControlName="city"  [(ngModel)]="newAttribute.city"  placeholder="City" >
</mat-form-field>
<br>

     <br><br><br><br>
        <button mat-flat-button    (click)="saveAddress(i,myForm)">Save</button>
</form> 
<br>
<hr>
</div>

Answer №2

When working with forms in Angular, it is important to access and manipulate data using form directives such as FormGroup and FormArray.

In your code, you attempted to combine data from a simple contacts array and integrate it with form controls.

Ensure that you create form groups for all the form elements correctly to align with your interface, and then utilize the data from these form groups on the form itself, especially if there is a need to modify it within the form.

By utilizing formControls on inputs, your data can be altered based on user input, allowing you to retrieve it using the .value property. When grouping data in formGroups, you can access all the aggregated data using formGroup.value, where you will find the entire structure and data you have created.

I have made updates to your stackblitz with some of the mentioned changes implemented. By continuing in this manner, you will achieve more maintainable and easily comprehensible code.

https://stackblitz.com/edit/angular-movie-read-load-json-sample-eg-l6awjk?file=src/app/app.component.html

Update

Check out the address edit example in this updated stackblitz: https://stackblitz.com/edit/angular-movie-read-load-json-sample-eg-w9ty9b?file=src/app/app.component.html

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

The rendering of the Angular 2 D3 tree is not functioning properly

Attempting to transition a tree created with d3 (v3) in vanilla JavaScript into an Angular2 component has been challenging for me. The issue lies in displaying it correctly within the component. Below is the code snippet from tree.component.ts: import { ...

Angular Observable returning null results

After spending some time on this issue, I am still puzzled as to why I am consistently receiving an empty observable. Service: import { Injectable } from '@angular/core'; import { WebApiService } from './web-api-service'; import { Beha ...

.observe({ action: (response) => { this.updateData = response.Items; }. what comes after this

I need some guidance on what comes next within the callback function .subscribe({ next: (data) => { this.newData = data.Items; } ...

After updating next.config, the NextJS + NextAuth middleware doesn't seem to be triggered

I'm currently utilizing <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b0ded5c8c49dd1c5c4d8f0849e81889e87">[email protected]</a> & <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemai ...

What To Do When You See "Unable to retrieve the 'get' property of an undefined or null reference" Error

I've encountered an error while trying to develop an application. The error message reads "Unable to get property 'get' of undefined or null reference at ProfilePage.prototype.ngOnInit". My framework of choice is Ionic 4. This error specif ...

Sign out from Azure Active Directory using the ADAL library in an Angular application written in TypeScript

When navigating multiple tabs in a browser, I am encountering an issue with logging out using adal. How can I successfully log out from one tab while still being able to use another tab without any hindrance? Currently, when I log out from one tab, it pr ...

Where can I find the refresh token for Azure Single Sign-On with MSAL?

Currently, I am working on integrating SSO for my application using Angular and .NET 2.2. I have come across a roadblock with the refresh token. While the login process is functioning correctly and the service is sending a lot of login information, the ref ...

Exploring Uppercase and Lowercase Filtering in NGXS for Angular Developers

I am encountering a problem with filtering and searching, specifically in matching the exact lowercase or uppercase of the string. Is there a way to search or filter regardless of the case sensitivity? For more information, please visit this link CLICK H ...

Adjust the placement of a div within another div based on various screen sizes dynamically

Currently, I am working on an Ionic 2 app where the user is required to select specific points on the screen. These coordinates will then be utilized on another screen with a different size. My initial attempt at using rule of three/cross multiplication pr ...

Error: Could not locate module: 'path' in ' ode_modulessource-map-support' - npm

During the migration process from Angular 5 to Angular 7, I encountered a couple of errors such as map and forkJoin being deprecated. Thankfully, those issues were resolved. However, there is still one lingering error that crops up when running ng serve. ...

Error message "Could not locate module while constructing image in Docker."

I've encountered an issue while working on my nodeJS Typescript project. After successfully compiling the project locally, I attempted to create a docker image using commands like docker build or docker-compose up, but it failed with a 'Cannot fi ...

Struggling to make the transition from JavaScript to TypeScript in Ionic 2

I recently updated the file extensions for my application files, including app/app.js. Error: Cannot find module 'app/app.js' from 'app_folder' The error message doesn't specify which file I need to locate to resolve the issue. ...

Troubleshooting problems encountered when duplicating an array in JavaScript

I am attempting to utilize properties and flatmap to modify an array without altering the original data. I have implemented this method in two different instances within a single dispatch call in Vue.js when transferring data from parent to children comp ...

Arrange the elements within the anchor tag in a vertical line using Angular Material

Is there a way to style the elements within an anchor tag in Angular Material so that they display in a single line? I am looking for the CSS solution to achieve this outcome. This is my current HTML code: <a mat-list-item [routerLink]="['das ...

Problem with Angular 2 Typings Paths in Typescript

Currently, I am in the process of learning how to create a Gulp build process with Angular 2 and Typescript. Following the Quick Start guide has allowed me to get everything up and running smoothly. However, I have decided to experiment with different fold ...

Issue with bi-directional data binding in Angular's matInput component

When working on my template... <input matInput placeholder="Amount" [(value)]="amount"> In the corresponding component... class ExampleComponent implements OnInit { amount: number = 0; ... } The binding doesn't seem to work as expect ...

The ngOnInit lifecycle hook is not triggered by the Angular routerLink

In the component.ts file, you will find the ngOnInit function as shown below: ngOnInit() { this.locationService.getLocation().subscribe( locations => { this.locations = locations; }); } <a [routerLink]="['/locations-list&apo ...

Testing MatSnackbar with Jasmine Karma in Angular: A Comprehensive Guide

I am seeking guidance on how to perform unit testing for the onSubmit function, which triggers a MatSnackbar message saying "Submitted Successfully" upon successful submission. I am new to Jasmine Karma and would appreciate assistance with testing the MatS ...

Angular 2: A Beginner's Guide to Creating Objects and Transforming Code from Angular to Angular 2

Currently, I am learning Angular 2 and facing an issue. I am unsure about how to create an object in my login function (Angular1). public logIn() { let phone = this.user.number.replace(/\s+/g, ''); let email = 'u&a ...

Error: The NgTools_InternalApi_NG_2 member is not exported in compiler-cli/src/ngtools_api

Currently, my ng serve command is not working and showing the following error message: ERROR in node_modules/@angular/compiler-cli/index.d.ts(20,10): error TS2305: Module '"./node_modules/@angular/compiler-cli/src/ngtools_api"' has no expor ...