Sisky
Sisky

Reputation: 603

Array undefined in Typescript but works in HTML

I have a component that populates an Object array in its ngInit() method from a service which I then use the contents of in my HTML template.

My problem is I can use this data fine in the HTML template but if I try to use this same Object array in my TypeScript file I will get an undefined error.

Below is a simplified code example of my problem:

@Component({
  selector: 'booking',
  template: `  
    <div *ngFor="let r of requestedBookings">
      <label>Requested on {{r.created | date: 'd MMM H:mm'}}</label>
    </div>
  `
})

export default class BookingComponent {

    requestedBookings: Object[];

    constructor(private bookingService: BookingService) {
      
    }
    
    ngOnInit() {
      
      this.getRequestLog();
      
      // Cannot read property 'length' of undefined error
      // console.log(this.requestedBookings.length);
      
    }
    
   
    private getRequestLog(): void {
      
      this.bookingService.getRoomRequestBooking(1,1,1)
        .subscribe(data => this.requestedBookings = (data as any))
        .results, err => {
          console.log(err);
        }

}

Why is it in the above example I can use the requestedBookings array as expected in the HTML template but inside the TypeScript file I receive undefined errors?

Upvotes: 0

Views: 2277

Answers (2)

Sisky
Sisky

Reputation: 603

I fixed this issue by using this constructor from the subscribe method. the complete parameter event happens after successful completion.

  subscribe(next?: (value: T) => void, 
            error?: (error: any) => void, 
            complete?: () => void): Subscription;

Code is as follows:

ngOnInit() {  
  this.getRequestLog();
}

private getRequestLog() {

  this.bookingService.getRoomRequestBooking(this.date, this.level, this.room)
    .subscribe(
      data => this.requestedBookings = (data as any).results,
      err => {
        console.log(err);
      },
      () => console.log(this.requestedBookings.length));

}

Upvotes: 0

pinkfloyd
pinkfloyd

Reputation: 255

IMHO the correct way should be something like:

ngOnInit() {  
this.getRequestLog();
}

private getRequestLog(): void {
  this.bookingService.getRoomRequestBooking(1,1,1)
    .subscribe((data)=>{
     this.requestedBookings = data;
     console.log(this.requestedBookings.length);
    })
    .results, err => {
      console.log(err);
    }
}

As explained before, the call to getRoomRequestBooking is async, so you should not expect it will finish before calling the console.log. Instead, you should use the requestedBookings.length value in a place where you do know it will exist. Hope it helps!!

Upvotes: 2

Related Questions