Розробка

Як зробити пошук користувачів з Github використовуючи Angular

Ця стаття є відповіддю на:
— Як зробити пошук користувачів з GitHub використовуючи React + RxJS 6 + Recompose,
— Як зробити пошук користувачів з GitHub без React + RxJS 6 + Recompose,
— Як зробити пошук користувачів з Github використовуючи VanillaJS.

Метою статті є:
— показати, що на Angular теж можна швидко написати просте додаток, хоча це не його основний коник,
— показати плюси програми на Angular.

Метою статті НЕ є:
— розпалювання чергового холівару.

Всім кому цікаво прошу під кат.

Підготовка

Для роботи з Angular необхідно встановити глобально angular CLI

npm install -g @angular/cli

Створюємо новий додаток

ng new github-ui
cd github-ui

Відразу створимо комопоненты користувача і помилки, і сервіс для отримання даних з github

ng generate component components/user
ng generate component components/error
ng generate service services/github

І підключимо їх в основний модуль програми.
Так-же підключимо модулі HttpClient (для роботи з http запитами) і ReactiveForms (для роботи з формами).

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]
})
export class AppModule {}

 

Моделі даних

Т. к. Angular використовує Typescript, а Typescript дає нам типізацію, то хорошою практикою є описувати моделі даних.
Це дає наступні плюси:
— зручний автокомпліт при роботі з додатком,
— перевірка збігу типів на стадії компіляції,
— дає іншим розробникам зрозуміти данні з якими вони працюють.

models/user.model.ts

export class User {
 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;
}

 

Сервіс для отримання даних

Роботу із запитами на сервер в Angular прийнято виносити в сервіси.
В раніше створений сервіс додамо метод для отримання даних користувача.

services/github.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Вами } from 'rxjs';
import { User } from '../models/user.model';

@Injectable()
export class GithubService {

 // Підключаємо модуль для роботи з http
 constructor(private http: HttpClient) {}

 // Метод для запиту користувача
 getUser(name: string): Вами<User> {
 const url = `https://api.github.com/users/${name}`;
 return this.http.get<User>(url);
}
}

 

Пошук користувача

У Angular з коробки вбудований RxJs. З допомогою нього і модуля роботи з формами ми можемо підписатися на зміну значення контрола, і отримати дані користувача.

app.component.html

<div class="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']
})
export class AppComponent implements OnInit {
 // Контрол для пошуку користувачів
 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;
});
}
}

 

Інші компоненти

Інші компоненти є «дурними», тобто не містять в собі логіки, а лише відображають отримані дані.

user component

<div class="github-card user-card">
 <div class="header User"></div>
 <a class="avatar"
[href]="'https://github.com/'+user.login">
 <img [src]="user.avatar_url+'&s=80'" [alt]="user.name" />
</a>
 <div class="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

<div class="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
})
export class ErrorComponent {}

 

Плюси використання Angular

— відділення отримання даних від роботи з ними,
— відділення шаблону від логіки,
— чітка і зрозуміла масштабована структура,
— вбудовані модулі для роботи з формами і сервером,
— вбудований RxJs для ассинхронної роботи,
— сувора типізація перевірка на наявність помилок при компіляції.

Вихідний код

github
live demo

Висновки

Як було показано вище будь-який додаток (особливо невеликий) можна написати використовуючи різні бібліотеки, фреймворки або чистий JS.

Більш важливим є знання інструментів, які ви використовуєте, і розуміння на скільки вони підходять в даній ситуації.

Всім успіхів у вивченні і чистого коду!

Related Articles

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *

Close