1

I have the following html code:

 <tbody ng-repeat="caterory in data">
        <tr>
            <td [colSpan]="segment">{{ caterory.name }}</td>
        </tr>
        <tr ng-repeat="room in caterory.rooms">
            <td>{{room.room_no}}</td>
            <td [colSpan]="schedule.dayDiff" ng-repeat="schedule in room.reservations">{{schedule.firstName}}</td>
        </tr>
    </tbody>

When I run I'm getting the following error:

TypeError: Cannot read property 'name' of undefined

After I googled cause is that data is nod loaded while template render. This is my component code: How to load data first and then render template?

ngOnInit() {  this.reservationService.getUserBranch(this.authservice.getUserID()).subscribe(data => {
      this.userBranch = data.json().branch;
      this.brSelectedValue = this.userBranch[0].id
      this.reservationService.getPerson('').subscribe(data => {
        this.persons = data.json().person;
      });
      // TO DO
      this.fillDataRange();
    });
  }

This fillDataRange is my function :

fillDataRange() { 
    this.reservationService.getReservation(this.brSelectedValue.toString(), this.intl.formatDate(this.dateFrom, 'yyyy-MM-dd'), this.intl.formatDate(this.dateTo, 'yyyy-MM-dd')).then(data => {
      this.data = data;
      console.log("Start", this.data);


      for (var i = 0; i < this.data.length; i++) { // Loop Through Categories
        if (this.data[i].rooms.length > 0) {
          for (var j = 0; j < this.data[i].rooms.length; j++) { // Loop Through Rooms from Category
            if (this.data[i].rooms[j].reservations.length > 0) {
              var sheduleArray = [];
              var a = 0;
              var d = a;
              var sumDayFiff = 0;
              for (var t = 0; t < this.data[i].rooms[j].reservations.length; t++) {
                var sheduleFrom = new Date(this.data[i].rooms[j].reservations[t].startDate);
                var sheduleTo = new Date(this.data[i].rooms[j].reservations[t].endDate);
                var status = this.data[i].rooms[j].reservations[t].status;
                var oneDay = 24 * 60 * 60 * 1000;
                var diffDays = Math.round(Math.abs((sheduleFrom.getTime() - sheduleTo.getTime()) / (oneDay)));
                for (a; a < this.segment; a++) {
                  var current = new Date(datesArray[d]);
                  if (current >= sheduleFrom && current <= sheduleTo) {
                    sheduleArray[a] = new Schedule(this.data[i].rooms[j].reservations[t].id, status, sheduleFrom, sheduleTo, this.data[i].rooms[j].reservations[t].id, this.data[i].rooms[j].reservations[t].id, this.data[i].rooms[j].reservations[t].id, this.data[i].rooms[j].reservations[t].id, diffDays, current, "reservationModal('" + current + "')", 'false', this.data[i].rooms[j].reservations[t].id, this.data[i].rooms[j].reservations[t].id);
                    a++;
                    d = d + diffDays;
                    sumDayFiff = sumDayFiff + diffDays;
                    break;
                  } else {
                    sheduleArray[a] = new Schedule("", 1, new Date(), new Date(), 1, "", "", "", 1, current, "reservationModal('" + current + "')", 'true', null, null);
                  }
                  d++;
                }
                sumDayFiff--;
              }
              for (a; a < this.segment - sumDayFiff; a++) {
                sheduleArray[a] = new Schedule("", 1, new Date(), new Date(), 1, "", "", "", 1, datesArray[d + 1], "reservationModal('" + 1 + "')", 'true', null, null);
                d++;
              }
              this.data[i].rooms[j].reservations = sheduleArray;
            } else {
              for (var f = 0; f < this.segment; f++) {
                this.data[i].rooms[j].reservations[f] = new Schedule("", 1, new Date(), new Date(), 1, "", "", "", 1, datesArray[f], "reservationModal('" + 1 + "')", '', null, null);
              }
            }
          }
        }
      }
      console.log("End", JSON.stringify(this.data));
    });
  }
4
  • You can try {{ caterory?.name }} : it should display nothing if the data is not loaded yet and load it once it's available Commented Aug 30, 2017 at 12:41
  • And if you really need to load the data first, you can use a resolve() function at the router level to tell the router to wait for this function to resolve the data and then load the route Commented Aug 30, 2017 at 12:42
  • I alredy try this <tbody ng-repeat="caterory in data"> <tr> <td [colSpan]="segment">{{ caterory?.name }}</td> </tr> <tr ng-repeat="room in caterory.rooms"> <td>{{room?.room_no}}</td> <td [colSpan]="schedule?.dayDiff" ng-repeat="schedule in room.reservations">{{schedule?.firstName}}</td> </tr> </tbody> but does not render dable body Commented Aug 30, 2017 at 12:44
  • I have filter on page, i want to first load data with default values and after if user choose custom filters also load appropriate data Commented Aug 30, 2017 at 12:45

1 Answer 1

3

You can use ?. instead of . to avoid errors in case the value before . is null

<tbody *ngFor="let caterory of data"> <!-- some changes in this line -->
    <tr>
        <td [colSpan]="segment">{{ caterory?.name }}</td> <!-- added ? -->
    </tr>
    <tr *ngFor="let room of caterory.rooms"> <!-- changes --->
        <td>{{room.room_no}}</td>
        <td [colSpan]="schedule?.dayDiff" *ngFor="let schedule of room.reservations">{{schedule?.firstName}}</td> <!-- changes -->
    </tr>
</tbody>

If you fix the ng-repeat (AngularJS) to the Angular 2 (4) syntax, you don't need ? anymore in this specific example, because Angular won't try to render {{ caterory?.name }} when data is not yet available.

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

3 Comments

I guess the only time I can be faster than you Günter is when I don't write a full answer and throw it out in the comments :-))
@AlexBeugnet sorry for that :D but I have troubles to place answers myself. Too much competition nowadays :-/
Sorry, no idea what kind of lazy loading you are talking about. If you are talking about the lazy loading of components by the Angular router, then yes, these two things are unrelated. (I'm not aware of another kind of lazy loading)

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.