I am trying to build an angular app for a personal project and my first webform is exhibiting behavior I don’t understand. I have an interface as follows with a service to update an array of that interface. The array is instantiated in the service from existing json. My component uses a checkItemForm to hold the data, then onSubmit() updates an item and pushes that item using the service. If I just pass this.newcheckitem, it is correctly handling the ID but the name only ever registers as and empty string. If I pass a new object with the name and id separately the behavior works as expected. What am I missing that is causing the name attribute to get wiped out?
Interface
export interface CheckItem { id: number; name: string; }
Service
export class ChecksService { items: CheckItem[] = checkItems; //Check items being an array of 2 check items held in assets constructor() { } addToChecks(checkItem: CheckItem){ this.items.push(checkItem); } }
Component in full
import { Component, OnInit } from '@angular/core'; import { FormBuilder } from '@angular/forms'; import { CheckItem } from '../check-item'; import { ChecksService } from '../checks.service'; import { checkItems } from 'src/assets/journaldata'; import { CheckItemComponent } from '../check-item/check-item.component'; @Component({ selector: 'app-new-check-item', templateUrl: './new-check-item.component.html', styleUrls: ['./new-check-item.component.css'] }) export class NewCheckItemComponent implements OnInit { private newCheckItem : CheckItem = {id: 5, name: "Why"}; checkItemForm = this.formBuilder.group({ checkName : '' }) onSubmit(): void { console.log(this.newCheckItem.name); this.newCheckItem.name = this.checkItemForm.value.checkName!; this.checkItemForm.reset(); console.log(this.newCheckItem.name); this.checkService.addToChecks(this.newCheckItem); this.checkService.addToChecks({id:5, name:this.newCheckItem.name}) console.log(checkItems); } constructor( private checkService: ChecksService, private formBuilder : FormBuilder ) {} ngOnInit(): void { } }
Console Output:
Why TestName (4) [{…}, {…}, {…}, {…}] 0: {id: 1, name: 'Test'} 1: {id: 2, name: 'Another Test'} 2: {id: 5, name: ''} 3: {id: 5, name: 'TestName'}
Advertisement
Answer
your function addToChecks
is adding a reference to the incoming CheckItem
to your array, not a copy. Thus, when you reset the name
of newCheckItem
to be empty (this.newCheckItem.name = ''
), the array is referencing the same object, and thus will show an empty name as well. Instead, what you can do is store a copy of the incoming parameter in your array:
addToChecks(checkItem: CheckItem){ this.items.push({ ...checkItem }); }