Build Your First Angular Website

Show a Single User Using Route Parameters

We now have our users section that lists our users. This works great, but now we have to show off a single user. The route to see a single user is defined by their username:

http://localhost:4200/users/:username

Here's the Angular route we have:

// src/app/users/user-routing.module.ts

const routes: Routes = [
  {
    path: '',
    component: UsersListComponent
  },
  {
    path: ':username',
    component: UserSingleComponent
  }
];

In order, to create links, we need to make sure that we have the RoutingModule loaded, which we do in AppModule's imports. Now we can use the routerLink directive to create links. In our UsersList component template, let's add an <a> tag with routerLink that points to the users/:username route:

<a routerLink="/users/{{ user.login }}">{{ user.login }}</a>

user.login is the username that comes back from the GitHub API.

Now when we click these, they go directly to the UserSingleComponent. We are still seeing user-single works! though. Let's adjust our UserSingleComponent to use this new route parameter.

Getting Route Parameters Inside a Component

Angular's router gives us access to something called the ActivatedRoute. This is the router's Observable for the current route; in this case, activated route will contain all the data for our /users/:username route.

We can subscribe to this Observable and pull the username out of it like so. First we import and inject the ActivateRoute:

// src/app/users/user-single.component.ts
import { ActivatedRoute } from '@angular/router';

// ...

export class UserSingleComponent implements OnInit { 

  // inject the ActivatedRoute as route
  constructor(private route: ActivatedRoute) {}

  ngOnInit() {}

}

Next, we subscribe to the route.params which is an Observable. We will do this in ngOnInit. By using the Observable, we ensure that this variable gets updated whenever the route changes. Let's say we navigate from one user page to another. This route parameter will update and Angular will be able to re-use the component instead of destroying and recreating. This is one of the ways Angular leads to better performance!

ngOnInit() {
  this.route.params.subscribe(params => {
    // get the username out of the route params
    this.username = params['username'];

    // now we can go grab user data from github    
  })
}

Getting Our User

Next up, let's go grab the information for our user. We need to:

  • add a user property on the class to hold this user
  • inject our UserService
  • use the UserService with a getUser() method (we'll create this method soon. wishful coding!)

We'll do all the above in our UserSingleComponent class:

// src/app/users/user-single.component.ts
// ...
import { UserService } from '../../user.service';

@Component({
  // ...
})
export class UserSingleComponent implements OnInit {
  user; // property to hold our user when we eventually grab them from github api

  // inject the things we need
  constructor(
    private route: ActivatedRoute,
    private userService: UserService
  ) {}

  // watch the route parameters for changes
  // every time it changes (or on first load), go get a user from userservice
  ngOnInit() {
    this.route.params.subscribe(params => {
      const username = params['username'];
      this.userService
          .getUser(username)
          .subscribe(user => this.user = user);
    });
  }
}

We're using the userService to getUser(username) and then subscribing to it.

Let's go create the getUser method now.

Getting a Single User from GitHub

The GitHub API allows us to grab a user based on their username: https://developer.github.com/v3/users/#get-a-single-user

The URL is https://api.github.com/users/:username. This is exactly like how we structured our URL.

Create a getUser method on the UserService:

// src/app/user.service.ts

getUser(username: string) {
  return this.http.get(`${this.apiUrl}/users/${username}`); 
}

We're using TypeScript's typings to let our developers and application know that username should be a string.

Now our application should be able to get a user!

Displaying Our User

Last, we can update our template to show this user:

<section class="section">
<div class="container">

  <div class="card" *ngIf="user">
    <img [src]="user.avatar_url">
    <h2>{{ user.login }}</h2>
  </div>

</div>
</section>