错误TypeError:无法读取未定义的属性'seatsavailable'

时间:2018-11-05 10:38:50

标签: angular typescript angular-decorator

我正在使用@Input和@Output装饰器在Angular 6项目中工作。我将Bookride组件作为父组件,将RideDetails作为子组件。 我可以使用@Input装饰器将数据从父组件成功传递到子组件,但是当我尝试将数据从子组件传递到父组件时,在控制台中出现以下错误

  

“错误TypeError:无法读取未定义的属性'seatsavailable'”

BookRide组件-HTML(父组件)

<tr *ngFor = "let book of shrides | filterpipe:filterargs" (click) = "message = book">
  <td>{{book.startloc}}</td>
  <td>{{book.destination}}</td>
  <td>{{book.seatsavailable}}</td>
  <td (click)="deleteProduct(book.id)"><a>DELETE</a></td>
  <td [routerLink] = "['/update-ride', book.id]" (click) = "update(book.id)"><a>UPDATE</a></td>

<app-ridedetails [cName] = "message" (onRegister)="courseReg($event)"></app-ridedetails>
  

在控制台中,错误在上一行显示为“错误TypeError:无法读取RestserviceService.push ../ src / app / restservice.service.ts.RestserviceService.updateRide2(restservice.service的未定义的属性'seatsavailable' .ts:84)“

BookRide组件-TS

export class RidedetailsComponent implements OnInit { 
seatsavailable: number;
courseReg(seatsavailable: number){
        console.log("Booking ID", seatsavailable);
        this.messages = `Booking Done. Your Booking name is : ${seatsavailable}`;
        this.render = !this.render;
}}

RideDetails组件-HTML(子组件)

     <tr>
          <td>{{loadData?.id}}</td>
          <td>{{loadData?.name}}</td>
          <td>{{loadData?.car}}</td>
          <td>{{loadData?.seatsavailable}}</td>
          <td>{{loadData?.startloc}}</td>
          <td>{{loadData?.destination}}</td>
      </tr>

<button type="button" (click)="register(loadData.id, loadData.seatsavailable)" [ngClass] = "render ? 'btn-primary' : 'btn-danger'"> {{render == true ? 'Book!' : 'Cancel! Booked ride'}} </button>

RideDetails组件-TS

export class RidedetailsComponent implements OnInit {
  loadData:any;
  sendData: any;
  messages: any;
  render: boolean = true;
  seatsavailable: number;
  ride: Ride[];
  constructor(private restservice : RestserviceService) { }

  ngOnInit() {
  }

  @Input() set cName(sampleObject){
    this.loadData=sampleObject;
  }

  //Child to Parent Communication
  //Sending an event to BookrideComponent and hide the table using @Output Decorator
  @Output() onRegister = new EventEmitter();

  register(bookingID: string, seatsavailable: number, ride: Ride) {
    this.render = !this.render;
    this.onRegister.emit({seatsavailable} as Ride);
    this.messages = `Booking Done(ridedetails). Your Booking id: ${bookingID}`;
    console.log("After clicking on Book button, the seats available data in ride details component is", this.loadData.seatsavailable);
    // console.log("seats avaiable in ride details component", this.loadData.seatsavailable);
    if(this.loadData.seatsavailable === seatsavailable){
      console.log("this.loadData.seatsavailable", this.loadData.seatsavailable - 1);
      this.restservice.updateRide2(ride, seatsavailable).subscribe( shride => { this.loadData.seatsavailable - 1 });
    } 
   }
}

我从RideDetails组件了解到的是,我创建了一个名为EventEmitter类型的onRegister属性,并附加了@Output装饰器,该属性使该属性可以将数据从子组件发送到父组件。稍后在register()内,它将seatavailable值发送回父组件。因此,一旦到达父组件,它就会以错误结束。

还在BookRide Component的courseReg()中,它将控制台渲染为您的预订名称为: [object Object]

2 个答案:

答案 0 :(得分:0)

此错误通常是由于在加载路由之前无法解析对象。因此,我们使用存在/安全运算符book?(存在-它是否“存在”)。如果错误是由此引起的,则最好的方法(除非您正在使用加载微调器)是利用Angular解析器,该解析器在加载路线之前解析组件中的数据。

如果您不熟悉,这是一本关于解析器的好文章:https://codeburst.io/understanding-resolvers-in-angular-736e9db71267

因此,在解决路由之前,您的数据将在组件中可用,并且您无需使用?来检查数据是否存在。

答案 1 :(得分:0)

一切似乎都是正确的,但是我对您的代码进行了一些更改-我不确定它是否可以工作,但是您可以尝试

this.onRegister.emit(seatsavailable);,如果您只是将seatsavailable从孩子发送给父母,只需将其值作为对象传递即可。

最后,当您读取自己的值时,可以这样读取-

courseReg(event: any){
        console.log("Booking ID", event.seatsavailable);
        this.messages = `Booking Done. Your Booking name is : ${event.seatsavailable}`;
        this.render = !this.render;
}}

我确定这可能有效,请尝试“谢谢”,祝您编码愉快!