Child component submission issue in edit form within Angular 2 application

Within my parent component, I've included a child component. When I click on the edit button, the edit form displays correctly and shows the previous data from the child component's select dropdown. However, if I choose not to select another option in the dropdown within the child component and submit the form to update the data, the form is submitted but the dropdown is posted as empty. On the other hand, if I click on the dropdown and either select the previous option or a new option, then the submit works properly.

parent.component.ts:

import { Component } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { JobsService } from '../jobs.service';
import { Validators, FormGroup, FormArray, FormBuilder, FormControl, NgForm } from '@angular/forms';
import { NgbDateParserFormatter } from '@ng-bootstrap/ng-bootstrap';


@Component({
  selector: 'job-edit',
  templateUrl: './parent.template.html',
  providers: [JobsService],
})

export class JobEditComponent {
  job: any = {};
  errorMessage: string;
  paramsObserver: any;
  public myForm: FormGroup;
  expireDate;
  publishDate;

  constructor(private _router: Router, private _route: ActivatedRoute, private _jobService: JobsService, private ngbDateParserFormatter: NgbDateParserFormatter) {}

  ngOnInit() {
    this.paramsObserver = this._route.params.subscribe(params => {
    let jobId = params['jobId'];
    this._jobService
     .read(jobId)
     .subscribe(
       job => {
        this.job = job;
        this.expireDate = new Date(this.job.expireDate);
        this.publishDate = new Date(this.job.publishDate);
        this.job.expireDate = { "year": this.expireDate.getFullYear(), "month": this.expireDate.getMonth(), "day": this.expireDate.getDate() } ;
        this.job.publishDate = { "year": this.publishDate.getFullYear(), "month": this.publishDate.getMonth(), "day": this.publishDate.getDate() } ;
       },
       error => this._router.navigate(['/jobs'])
     );
   });
  }

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

  update(form: NgForm) {
    this.job = form.value;
    let publishDate = this.job.publishDate;
    let expireDate = this.job.expireDate;
    let publishDateFormated = this.ngbDateParserFormatter.format(publishDate);
    let expireDateFormated = this.ngbDateParserFormatter.format(expireDate);
    this.job.publishDate = publishDateFormated;
    this.job.expireDate = expireDateFormated;
    this._jobService
      .update(this.job)
        .subscribe(savedJob => this._router.navigate(['/jobs', savedJob._id]), error => this.errorMessage = error);
 }
}

parent.template.html:

<form #myForm="ngForm" novalidate>
  <div class="row">
    <div class="col-sm-6">
      <div class="form-group">
        <contract-type name="contractType" [job]="job" ngModel ngDefaultControl></contract-type>
      </div>
    </div>
  </div>
  <button type="button" (click)="update(myForm)" class="btn btn-primary"><i class="fa fa-save">Save</i></button>
</form> 

This is my child component:

import { Component, Input } from '@angular/core';
import { Http } from '@angular/http';
import { NgForm, ControlValueAccessor } from '@angular/forms';

@Component({
  selector: 'contract-type',
  template: `
    <div *ngIf="contractTypes">
      <label class="form-control-label" for="contractType">Contract Type</label>
      <select id="contractType" name="contractType" required [(ngModel)]="job.contractType" class="form-control">
        <option value="0" selected>Select an item</option>
        <option *ngFor="let contractType of contractTypes" [value]="contractType.name_en">{{ contractType.name_en }}</option>
      </select>
    </div>
    `
})

export class ContractTypeComponent {
  private contractTypes;
  @Input() job;
  constructor(private _http: Http) {
    this._http.get('/api/contractTypes')
     .subscribe((res)=>{
       this.contractTypes = res.json();
    });
  }
}

View of the edit form with default previous data: https://i.sstatic.net/FjDci.png

If I click the submit button without selecting an option from the contract type dropdown, the post data shows an empty dropdown. However, if I click on the dropdown and then select an option, that selection is posted. https://i.sstatic.net/qoEKM.png

Note: I'm using the child component for add functionality as well, which is why I chose to make it a separate component for reusability.

After submitting, the form appears like this: https://i.sstatic.net/T5MuL.png

Answer №1

To fix the issue, simply delete the line this.job = form.value; from the parent component's update function. It's unclear why form.value is providing incorrect data.

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

Parent/Child Relationships in Typescript

Unraveling the Parent/Child Directive Mystery in Angular2/Typescript As I delve into the world of Angular2/Typescript/javascript, there is still much for me to learn. My current project involves a card game where each of the 2 players holds a hand of 5 ca ...

Tips for converting a toolbar into a side navigation bar when resizing the window (shrinking)?

Check out this example When the browser is maximized, it should show the toolbar and its content. However, if the browser window is resized, a new side nav bar should appear. How can I implement this feature? How do I utilize media queries to achieve this ...

Angular 2 offers the ability to crop and save images effortlessly

Utilizing ngImgCrop, I have been able to upload images and crop them successfully. Now, I am trying to figure out how to save the result-image from <img-crop image="myImage" result-image="myCroppedImage"></img-crop> to a folder in ASP.NET MV ...

How to implement an Angular Animation that is customizable with an @Input() parameter?

Have you ever wondered if it's possible to integrate custom parameters into an Angular animation by passing them through a function, and then proceed to use the resulting animation in a component? To exemplify this concept, consider this demo where t ...

When TypeScript in IntelliJ fails to generate JavaScript files after enabling the tsconfig declaration

In my tsconfig file, I have the following setup: { "compilerOptions": { "module": "ESNext", "target": "es6", "sourceMap": true, "rootDir": "./&qu ...

What is the best method for obtaining the li-Element in "Angular2 for TypeScript" (beta) so that I can apply a particular CSS class to it?

In my Angular2 application, I am working on creating a search functionality similar to Google's search where the results are displayed in a box. While I have successfully implemented this feature and it is functioning properly, one issue remains. When ...

Understanding how to interpret SiteMinder header within Angular 4

Currently, I'm integrating SiteMinder for SingleSignOn (SSO) authentication. After a successful authentication, I need to know how to access the SM_USER header from SiteMinder within my Angular 4 code. Is there anyone who could assist me in retrievin ...

What is the process for creating static pages that can access local data within a NextJS 13 application?

I recently completed a blog tutorial and I must say, it works like a charm. It's able to generate dynamic pages from .md blog posts stored locally, creating a beautiful output. However, I've hit a roadblock while attempting what seems like a sim ...

What could be causing my application to not locate the jquery module? ERROR: ENOENT: The specified file or directory cannot be found

I've decided to bring over an Angular project that already has a bootstrap template integrated into my own project. (Still unsure if this was the right move) One of the steps I took was adding these lines to the angular.json file: "styles": [ ...

Injecting ngx-bootstrap modules into a child module in Angular 4: Step-by-step guide

My current application folder structure is set up as follows: >app app.module.ts app.routing.ts >>auth login.component auth.module.ts atuh.routing.module.ts Now, I have a requirement to incorporate the ngx-intl-input module into my pro ...

mat-tab-group - Positions elements in the center, right, and left for optimal alignment

Is it possible to align the buttons in a mat-tab-group to the left, center, and right positions? I am using mat-tabs. How can I have elements with "left" align to the left, elements with "center" in the center, and elements with "right" align to the right? ...

"Is it possible to disable the transition animation in mat-sidenav of Angular Material without affecting the animations of

My Angular application features a mat-sidenav that is organized like this: <mat-sidenav-container> <mat-sidenav [mode]="'side'"> <!-- Sidenav content --> </mat-sidenav> <mat-sidenav-content ...

The technique for ensuring that all subscriptions are completed within a for loop before moving forward

In my app, I have a scenario where I need to fetch JSON data in a series of "category data" subscriptions inside a for loop. This data is then filtered based on the user's current location. The issue I'm facing is that my app doesn't wait fo ...

Angular-oauth2-oidc does not successfully retrieve the access token when using OAuth2 and SSO

Here's an issue I'm facing: I've been attempting to integrate SSO and OAuth2 flow using angular-oauth2-oidc. When testing with POSTMAN and ThunderClient in VS Code, I managed to receive the correct response (the access_token). However, I am ...

Typescript is failing to perform type checking

I'm encountering an issue while trying to utilize TypeScript type checking with the following code snippet: abstract class Mammal { abstract breed(other: Mammal); } class Dog extends Mammal { breed(other: Dog) {} } class Cat extends Mammal { ...

RXJS - Trigger a function based on a specific condition being fulfilled by a value emitted from an observable

I have created a search field with autocomplete functionality. By using an observable that monitors changes in the text field, I am able to trigger actions based on user input. this.term.valueChanges .debounceTime(300) .distinctUntilChange ...

Using ngFor to Filter Tables in Angular 5

Are you in the midst of implementing multiple data filters in an Angular Application that displays data using a Table and ngFor? You may have explored different methods such as using Pipe in Type Script, but discovered that it is not recommended accordin ...

Using formControlName with an Ionic2 checkbox allows for seamless integration of

Currently facing an obstacle with checkboxes in ionic2. Here is how I am using the checkbox: <ion-item> <ion-label>Agree</ion-label> <ion-checkbox color="dark" id="agree" name='agree' class="form-control" formContro ...

The compilation process of the Angular 16 ng library build encounters issues with Ivy in full mode

After updating my Angular application from version 10 to version 16, I encountered an issue when trying to build my local Angular libraries. The error message received was: "✖ Compiling with Angular sources in Ivy full compilation mode." Here ...

What is the process for uploading an array of files with AngularFire2 and Firebase Storage?

I encountered a dilemma trying to find answers to my question. Most resources, like the AngularFire2 documentation and an informative tutorial from angularfirebase.com, only demonstrate uploading one file at a time. As I aim to construct a photo gallery CM ...