0

I have a problem with Angular 2 routing. When I click on my link to get the team details, it takes the right route and loads the component specified (TeamComponent). But, immediately "gets back" to the previous component (TeamsComponent), which is the teams list.

This is the structure of my project:

/app |_shared |_team |_team.component.css |_team.component.html |_team.component.ts |_team.model.ts |_team.service.ts |_team-list |_team-list.component.css |_team-list.component.html |_team-list.component.ts |_teams |_teams.component.css |_teams.component.html |_teams.component.ts |_teams.module.ts |_teams-routing.module.ts 

First, I set the routes on teams-routing.module.ts:

import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { TeamsComponent } from './teams.component'; import { TeamComponent } from '../shared/team/team.component'; const teamsRoutes: Routes = [ { path: 'team/:id', component: TeamComponent },{ path: 'teams', component: TeamsComponent } ]; @NgModule({ imports: [ RouterModule.forChild(teamsRoutes) ] }) export class TeamsRoutingModule { } 

Load the team list from the teamService on teams.component.ts and send it to team-list on teams.component.html:

import { Component, OnInit } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/observable/from'; import { TeamService } from '../shared/team/team.service'; import { Team } from '../shared/team/team.model'; @Component({ selector: 'app-teams', templateUrl: './teams.component.html', styleUrls: ['./teams.component.css'] }) export class TeamsComponent implements OnInit { teamList: Team[] = []; constructor(private teamService: TeamService) { } ngOnInit() { this.teamService.getTeams().subscribe(teams => { Observable.from(teams).subscribe(team => { this.teamList.push(team); }); }); } } 

teams.component.html

<section class="teams"> <app-team-list [teams]="teamList"></app-team-list> </section> 

Then, with my teams list, I set the HTML list on team-list.component.html:

<section *ngFor="let team of teams" class="team_list"> <div class="card" style="width: 20rem;"> <img class="card-img-top" src="/assets/logos/{{team.logo}}" alt="Team Logo"> <div class="card-block"> <h4 class="card-title">{{team.name}}</h4> <p class="card-text">{{team.location}}</p> <a routerLink="/team/{{team.id}}" class="btn btn-primary">Team Info</a> </div> </div> </section> 

Finally, I get the team info from param "id" and the service in team.component.ts:

import { Component, Input, OnInit } from '@angular/core'; import { Router, ActivatedRoute, Params } from '@angular/router'; import { Team } from './team.model'; import { TeamService } from "./team.service"; import 'rxjs/add/operator/switchMap'; @Component({ selector: 'app-team', templateUrl: './team.component.html', styleUrls: ['./team.component.css'] }) export class TeamComponent implements OnInit { team: Team = null; constructor(private teamService: TeamService, private activatedRoute: ActivatedRoute, private router: Router ) {} ngOnInit() { let teamId: number = this.activatedRoute.snapshot.params['id']; console.log("Vamos a buscar el equipo"); this.teamService.getTeamById(teamId).subscribe(team => this.team = team); } 

}

It loads the TeamComponent HTML with the team data, but gets back to /teams direction (and doesn't print the team list). I tried to change the routes names (/detail/:id for example) but still doesn't work. Any suggestions? Thanks in advance.

5
  • Does the route "teams" works the first time? Commented May 29, 2017 at 8:52
  • And how does your TeamService looks like? Commented May 29, 2017 at 9:00
  • Yeah @MarkusKollers, when I go to "/teams" for the first time, it prints the correct list. Commented May 29, 2017 at 9:24
  • I've build a clean angular-cli project and added your components and your service, and it works. Do you get any errors in your developer-console (F12)? Commented May 29, 2017 at 9:32
  • @MarkusKollers it says the property binding fields are null (ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'name' of null TypeError: Cannot read property 'name' of null at Object.eval [as updateRenderer] (TeamComponent.html:5) at Object.debugUpdateRenderer [as updateRenderer] (core.es5.js:12822)). It's like the route /team/19 (for example) isn't working, and it's trying to render TeamComponent on /teams. In fact, at the Network section in Chrome debugger, /team/19 is never called. Very, very strange. Commented May 29, 2017 at 10:02

2 Answers 2

1

Ok, got it. Your request will be exuted async, so at the creation-time of your component, team is null. I think you have a binding like this in your TeamComponent:

{{ team.name }} 

If team is null, name cannot be accessed and it crashes. To be sure the html will be rendered without errors, use the elvis-operator like this:

{{ team?.name }} 

This will only access name if team is not null or undefined

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

1 Comment

That's it. What a beginner stupid mistake :( Thank you very much Markus. Lesson learned.
0

Update: The getTeamById service

getTeamById(id: number): Observable<Team> { let team: Team = null; return this.http.get(this.urlTeams+'/'+id) .map(response => { let dbTeam: any = response.json(); for(let i in dbTeam) { team = new Team(dbTeam[i].teamId,dbTeam[i].teamName,dbTeam[i].teamLocation,dbTeam[i].teamFoundation,dbTeam[i].teamDivision,dbTeam[i].teamConference,dbTeam[i].teamStadium,dbTeam[i].teamAttendance,dbTeam[i].teamLogo,dbTeam[i].teamStadiumPhoto); } return team; }) .catch(this.handleError); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.