5

I'm getting these errors even though the values renders in the browser. I'm not sure how to fix this.

ERROR TypeError: Cannot read property 'length' of undefined

ERROR TypeError: Cannot read property 'FirstName' of undefined

Component.ts:

teams: Team[];

ngOnInit() {
  this.getTeams();
}

constructor(private m: DataManagerService, private router: Router) { 
}

getTeams(): void {
  this.m.getTeams().subscribe(teams => this.teams = teams);
}

select(em: Team){
  this.router.navigate(['/teamView',em._id]);
}

Component.html:

<div class="panel-body">
  <table class="table table-striped">
    <tr>
      <th>Team name</th>
      <th>Name of Team Leader</th>
    </tr>
    <tr *ngFor='let team of teams' (click)="select(team)">
      <td>{{team.TeamName}}</td>
      <td>{{team.TeamLead.FirstName}} {{team.TeamLead.LastName}}</td>
    </tr>
  </table>
  <hr>
</div>

Team.ts:

export class Team {
    _id: string;
    TeamName: string;
    TeamLead: Employee;
    Projects:{};
    Employees: {};
}

Object:

https://lit-coast-73093.herokuapp.com/teams

DataManagerService.ts

teams: Team[];
projects: Project[];
employees: Employee[];

constructor(private http: HttpClient) { 
}

getTeams(): Observable<Team[]> {
    return this.http.get<Team[]>(`${this.url}/teams`)
  }

getProjects(): Observable<Project[]> {
    return this.http.get<Project[]>(`${this.url}/projects`)
}

getEmployees(): Observable<Employee[]> {
    return this.http.get<Employee[]>(`${this.url}/employees`)
}
4
  • 1
    .length was just getting the size of the object. It works if I remove <td>{{team.TeamLead.FirstName}} {{team.TeamLead.LastName}}</td> Commented Apr 8, 2018 at 20:36
  • @John C : can you edit and add the code for select(team) to your question ? Commented Apr 8, 2018 at 20:37
  • @HDJEMAI select(team) is in component.ts Commented Apr 8, 2018 at 20:39
  • What is the content of Project class. Commented Apr 8, 2018 at 21:04

2 Answers 2

3

Because teams is probably not yet available,

you can try this way:

<div class="panel-body">
  <table class="table table-striped">
    <tr>
      <th>Team name</th>
      <th>Name of Team Leader</th>
    </tr>
    <tr *ngFor='let team of teams' (click)="select(team)">
      <td>{{team.TeamName}}</td>
      <td>{{team.TeamLead?.FirstName}} {{team.TeamLead?.LastName}}</td>
    </tr>
  </table>
  <hr>
</div>

Working demo:

https://stackblitz.com/edit/angular-tutorial-2yzwuu?file=app%2Fapp.component.html

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

1 Comment

You don't need the ? after team, as team will never be null. If it were null, the *ngFor would never be entered.
2
<tr *ngIf='teams.length > 0' *ngFor='let team of teams' (click)="select(team)">
  <td>{{team?.TeamName}}</td>
  <td>{{team?.TeamLead?.FirstName}} {{team?.TeamLead?.LastName}}</td>
</tr>

Possibilities : a) Teams object hasn't been populated yet. Hence there is nothing to iterate over b) Your API response doesn't have all the expected properties.

Adding checks like I suggested above should fix your problem. LMK if I can explain further.

2 Comments

Actually I think you should change the *ngIf here to: *ngIf='teams != null && teams.length > 0' otherwise if getTeams() returns null, this will error with Cannot read property 'length' of null
This doesn't even compile. Error: Template parse errors: Can't have multiple template bindings on one element. Use only one attribute named 'template' or prefixed with *

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.