0

I am fairly new to Angular. The version I am using in Angular 7.

So, I have a list of cars in cars.component.ts which are being fetched from a JSON file using a service. Each car in the list has an edit and delete option and I also have a button to add a new car.

The edit option has an update option and when I press that, I get an error ERROR TypeError: Cannot set property 'name' of undefined. I am missing out something but not sure what exactly.

Below is the code.

cars.component.ts

import { Component, OnInit } from '@angular/core';
import { CarService } from '../service/car.service';
import { ICars } from '../cars';

@Component({
  selector: 'app-cars',
  templateUrl: './cars.component.html',
  styleUrls: ['./cars.component.css']
})
export class CarsComponent implements OnInit {

  public cars = [];

  registeredCars = [];
  selectedRow: number;
  public car: ICars;
  showNew: Boolean = false;
  submitType: string;
  loading: Boolean = false;

  constructor(private _carService: CarService) { }

  ngOnInit() {
    this.loading = true;
    //console.log('loading', this.loading);
    this._carService.fetchData().subscribe(data => this.cars = data);
  }

  onEdit(index: number) {
    this.selectedRow = index;
    this.car = new ICars;
    this.car = Object.assign({}, this.cars[this.selectedRow]);
    this.showNew = true;
    this.submitType = 'Update';
  }

  onDelete(index: number) {
    this.cars.splice(index, 1);
  }

  onNew() {
    this.car = new ICars;
    this.submitType = 'Save';
    this.showNew = true;
  }

  onSave(index: number) {
    this.selectedRow = index;
    if (this.submitType === 'Save' ) {
      this.cars.push(this.car);
    } else {
      console.log('this car', this.car.name);
      this.car[this.selectedRow].name = this.car.name;
      this.car[this.selectedRow].year = this.car.year;
    }
    this.showNew = false;
  }

  onCancel() {
    this.showNew = false;
  }
}

and this is partial code

<div class="carsList">
  <table *ngIf="loading" class="table table-striped">
    <thead >
      <tr>
        <th>#</th>
        <th>Name</th>
        <th>Year</th>
      </tr>
    </thead>
    <tbody >
        <tr *ngFor="let car of cars; let i = index">
            <td>{{ i+1 }}</td>
            <td>{{car.name | uppercase}}</td>
            <td>{{car.year}}</td>
            <td>
                <button type="button" class="btn btn-info" routerLink="/car-details/{{ i }}" placement="top" ngbTooltip="View details"><fa name='eye'></fa></button>
              </td>
            <td>
              <button type="button" class="btn btn-secondary" (click)="onEdit(i)" placement="top" ngbTooltip="Edit details"><fa name='edit'></fa></button>
            </td>
            <td>
              <button type="button" class="btn btn-danger" (click)="onDelete(i)" placement="top" ngbTooltip="Delete entry"><fa name='trash'></fa></button>
            </td>
        </tr>
    </tbody>
  </table>
  <div class="text-right">
      <button type="submit" class="btn btn-primary" (click)="onNew()">New</button>
  </div>
</div>
<!-- Edit/Add User  -->

<div class="regentry" *ngIf="showNew">
    <h2 class="text-center">{{ submitType === 'Save'? 'Register New Car' : 'Edit Car' }}</h2>
    <br>
    <form (ngSubmit)="onSave()">
      <div class="form-group row">
        <label for="name-input" class="col-2 col-form-label">Car Name</label>
        <div class="col-10">
          <input class="form-control" type="text" [(ngModel)]="car.name" name="name" required>
        </div>
      </div>
      <div class="form-group row">
        <label for="year-input" class="col-2 col-form-label">Year</label>
        <div class="col-10">
          <input class="form-control" type="text" [(ngModel)]="car.year" name="year" required>
        </div>
      </div>
      <button type="submit" class="btn btn-success">{{submitType}}</button>&nbsp;
      <button type="submit" class="btn btn-primary" (click)="onCancel()">Cancel</button>
    </form>
  </div>

  <div *ngIf="!loading"><img class="loading" src="../../assets/loading.gif" alt="loading" srcset=""></div>
3
  • Perhaps the error stems from not properly calling the constructor function ICars? new ICars() Commented Jan 25, 2019 at 6:27
  • @BenSteward ohkay... can you please elaborate, I am very new to angular and this interface concept. Commented Jan 25, 2019 at 6:38
  • If it’s an interface, then I’m not sure how to use the new keyword with it. You’ll have to research that question. I think my answer solves your immediate question, however. Commented Jan 25, 2019 at 6:41

1 Answer 1

1

You need to pass the index you are saving to your onSave function in your template: onSave(index)

However, it would be simpler, since you are already setting the selectedRow in the onEdit function, to simply remove the parameter from onSave altogether and then remove the line this.selectedRow = index.

Because you weren’t passing a parameter, index was undefined and then you assigned that undesirable value to this.selectedRow before using it to look up a value on this.car.

Removing the lines I mentioned should keep this.selectedRow in tact as a valid index number at the time you click to save.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.