How to do a user search on Github using Angular

  • Tutorial
image

This article is a response to:


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!

Also popular now: