How to do a user search on Github using Angular
- Tutorial

This article is a response to:
- How to search for users on GitHub using React + RxJS 6 + Recompose ,
- How to search for users on GitHub without React + RxJS 6 + Recompose ,
- How to search for users on Github using VanillaJS .
The purpose of the article is:
- show that you can quickly write a simple application to Angular, although this is not its main reason,
- show the advantages of the application on Angular.
The purpose of the article is NOT:
- inciting another holivar.
All who are interested, please under the cat.
Training
To work with Angular, you must install a globally angular CLI.
npm install -g @angular/cli
Create a new application
ng new github-ui
cd github-ui
Immediately create user komponentsy and errors, and a service for receiving data from github
ng generatecomponent components/user
ng generatecomponent components/error
ng generate service services/github
And connect them to the main application module. Let's
also connect the modules HttpClient (for working with http requests) and ReactiveForms (for working with forms).
app.module.ts
import { BrowserModule } from'@angular/platform-browser';
import { NgModule } from'@angular/core';
import { ReactiveFormsModule } from'@angular/forms';
import { HttpClient } from'@angular/common/http';
import { AppComponent } from'./app.component';
import { UserComponent } from'./components/user/user.component';
import { ErrorComponent } from'./components/error/error.component';
import { GithubService } from'./services/github.service';
@NgModule({
declarations: [AppComponent, UserComponent, ErrorComponent],
imports: [BrowserModule, ReactiveFormsModule, HttpClient],
providers: [GithubService],
bootstrap: [AppComponent]
})
exportclassAppModule {}
Data models
Because Angular uses Typescript , and Typescript gives us typing, then it is good practice to describe data models.
This gives the following advantages:
- convenient autocomplete when working with the application,
- type matching at the compilation stage,
- gives other developers to understand with what data they work.
models / user.model.ts
exportclassUser {
login: string;
id: number;
node_id: string;
avatar_url: string;
gravatar_id: string;
url: string;
html_url: string;
followers_url: string;
following_url: string;
gists_url: string;
starred_url: string;
subscriptions_url: string;
organizations_url: string;
repos_url: string;
events_url: string;
received_events_url: string;
type: string;
site_admin: boolean;
name: string;
company: string;
blog: string;
location: string;
email: string;
hireable: string;
bio: string;
public_repos: number;
public_gists: number;
followers: number;
following: number;
created_at: string;
updated_at: string;
}
Service to get data
Work with requests to the server in Angular decided to make a service .
In the previously created service we will add a method for getting user data.
services / github.service.ts
import { Injectable } from'@angular/core';
import { HttpClient } from'@angular/common/http';
import { Observable } from'rxjs';
import { User } from'../models/user.model';
@Injectable()
exportclassGithubService{
// Подключаем модуль для работы с httpconstructor(private http: HttpClient) {}
// Метод для запроса пользователя
getUser(name: string): Observable<User> {
const url = `https://api.github.com/users/${name}`;
returnthis.http.get<User>(url);
}
}
Search user
RxJs is built into the Angular out of the box . With the help of it and the module for working with forms, we can subscribe to a change in the value of the control, and obtain user data.
app.component.html
<divclass="container"
[class.ready]="!!user"><input [formControl]="findControl"placeholder="GitHub username" /><app-user *ngIf="user"
[user]="user"></app-user><app-error *ngIf="error"></app-error></div>
app.component.ts
import { Component, OnInit } from'@angular/core';
import { FormControl } from'@angular/forms';
import { GithubService } from'./services/github.service';
import { User } from'./models/user.model';
import { filter, switchMap, debounceTime, catchError } from'rxjs/operators';
import { EMPTY } from'rxjs';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
exportclassAppComponentimplementsOnInit{
// Контрол для поиска пользователей
findControl = new FormControl();
// Ошибка поиска
error: boolean = false;
// Найденный пользователь
user: User = null;
// Подключение githubService для поиска пользователяconstructor(private githubService: GithubService) {}
// Хук инициализации компонента
ngOnInit() {
this.findControl.valueChanges
.pipe(
// Фильтруем если введено меньше двух символов
filter(value => value.length > 2),
// Ставим задержку одну секунду
debounceTime(1000),
// Запрашиваем данные пользователя
switchMap(value =>this.githubService.getUser(value).pipe(
// Обработка ошибок
catchError(err => {
this.user = null;
this.error = true;
return EMPTY;
})
)
)
)
// Получение данных
.subscribe(user => {
this.user = user;
this.error = false;
});
}
}
The remaining components
The remaining components are “stupid”, i.e. do not contain logic, but only display the data.
user component
<divclass="github-card user-card"><divclass="header User"></div><aclass="avatar"
[href]="'https://github.com/'+user.login"> <img [src]="user.avatar_url+'&s=80'" [alt]="user.name" /> </a><divclass="content"> <h1>{{user.name}}</h1> <ul class="status"> <li> <a [href]="'https://github.com/'+user.login+'?tab=repositories'"> <strong>{{user.public_repos}}</strong>Repos </a> </li> <li> <a [href]="'https://gist.github.com/'+user.login"> <strong>{{user.public_gists}}</strong>Gists </a> </li> <li> <a [href]="'https://github.com/'+user.login+'/followers'"> <strong>{{user.followers}}</strong>Followers </a> </li> </ul></div></div>
import { Component, Input, ChangeDetectionStrategy } from'@angular/core';
import { User } from'../../models/user.model';
@Component({
selector: 'app-user',
templateUrl: './user.component.html',
styleUrls: ['./user.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class UserComponent {
@Input()
user: User;
}
error component
<divclass="error"><h2>Oops!</h2><b> User not found.</b><p>Please try searching again.</p></div>
import { Component, OnInit, ChangeDetectionStrategy } from'@angular/core';
@Component({
selector: 'app-error',
templateUrl: './error.component.html',
styleUrls: ['./error.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
exportclassErrorComponent {}
Pros of using Angular
- separation of data from work with them,
- separation of the pattern from logic
- clear and understandable scalable structure
- built-in modules for working with forms and server
- built-in RxJs for asynchronous operation,
- strong typing checking for errors during compilation.
Source
github
live demo
findings
As was shown above, any application (especially small) can be written using different libraries, frameworks or pure JS .
More important is the knowledge of the tools you use, and an understanding of how suitable they are in a given situation.
All success in learning and clean code!