Angular 5 HttpInterceptor : show and hide loader

اگر از افرادی باشید که در حال کار کردن روی یک پروژه انگیولاری هستند ، به احتمال زیاد به این مسئله برخوردین که بخواین در زمانی که سرور قرار جواب request های کاربر را بده ، یک loader نمایش بدین تا هم کاربر نتونه روی جای دیگه ای در صفحه کلیک کنه و هم حسی را به کاربر تلقین کنید که کار شما در حال انجام شدنه و تا چند ثانیه دیگه نتیجه مورد نظر خودتون رو میگیرید.

مدت ها بود که به این مسئله فکر میکردم و میخواستم یک interceptor روی HTTP انگیولار بنویسم. پروژه ام روی انگیولار ۵ بود اما هنوز وقت نکرده بودم که پروژه ام رو از HTTP به HTTP Client ببرم و این خودش یک مشکل بزرگ بود و نوشتن interceptor روی HTTP تقریبا یک کار سخت و طاقت فرسا بود ، چون خود انگیولار براش این امکان را پیاده سازی نکرده بود و افرادی هم که این کار را کرده بودند با هزار trick این کار را انجام داده بودن و ظاهر جالبی نداشت و از اون طرف لایبراری های آماده ای هم که توی گیت هاب وجود داشت هیچ کدوم جواب گوی نیاز من نبودند. پس تصمیم گرفتم در مرحله اول پروژه را به HTTP Client ببرم چون نوشتن interceptor بر روی آن بسیار کار راحتی بود و خود انگیولار روش درست این کار رو recommend کرده بود .

در ابتدا میخواستم خودم یک interceptor بنویسم و درون اون از یک لودر استفاده کنم که به محض اینکه request ها زده میشه اون لودر را نمایش بدم که با یک library خوب به اسم ng-http-loader آشنا شدم که اصلا نیازی به نوشتن interceptor هم نداشت و در واقع با استفاده ازش خودش این کار را براتون انجام میداد.

میتونید demo این لایبراری را اینجا مشاهده کنید

در اینجا نحوه استفاده از این library و مشکلی که خودم روی انگیولار ۵ باهاش داشتم و حل شد را براتون توضیح میدم و لینک github اش را در اینجا قرار میدم



مرحله اول

اگر از انگیولار ۵ استفاده میکنید آخرین ورژن سازگار باهاش ۰.۹.۱ هست پس باید خط زیر را در فایل package.json پروژتون قرار بدین . باز هم تاکید میکنم که این لایبراری تنها در صورتی روی request هاتون کار میکنه که از HTTPClientModule استفاده کرده باشین.

"ng-http-loader":"0.9.1",

و بعدش یک بار npm install یا yarn install را بسته به package manager ای که استفاده میکنید را اجرا کنید تا فایل هاش به پوشه node_modules اضافه بشه

مرحله دوم

داخل app.module تون در قسمت import کافیه که NgHttpLoaderModule را import کنید و در قطعه کد زیر به محلی که این ماژول را import کردیم دقت کنید(منظورم آدرسش از پوشه node_modules هست).چون دقیقا اینجا نقطه ای بود که خودم مشکل داشتم و با سوالی که توی issue های پروژه زدم متوجه این نکته شدم و دوستان عزیز زحمت کشیدن و فایل readme مخصوص به این ورژن را (که سازگار با انگیولار ۵ بود) برام ارسال کردن که لینکش را اینجا قرار میدم

قسمت هایی که باید شما به پروژتون اضافه کنید را با * نشانه گذاری کردم

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
[...]
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http'; <============
import { NgHttpLoaderModule } from 'ng-http-loader/ng-http-loader.module'; //******

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule, <============ (Perform http requests with this module)
    NgHttpLoaderModule, //کافیه که این را اضافه کنید****
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }


مرحله سوم

در این مرحله کافیه که از<spinner> </spinner> در app.component.html خود استفاده کنید و تمام ، مانند کد زیر

import {Component, OnInit, ViewContainerRef} from '@angular/core';
import {LayoutService} from "./shared/layout/layout.service";
import {Spinkit} from 'ng-http-loader/spinkits';

@Component({
    selector: 'app-root',
    template: `<router-outlet></router-outlet>
                <spinner 
                    [backgroundColor]="'#232f3e'"
                    [spinner]="spinkit.skThreeBounce"
                    [debounceDelay]="10">
                </spinner>`
})
export class AppComponent implements OnInit {
    public title = 'app works!';
    public spinkit = Spinkit;
    
    public constructor(private viewContainerRef: ViewContainerRef,
                       private layoutService: LayoutService,
                       private http: HttpClient,) {
    }

    ngOnInit() {
    }
}

همینطور ثابت Spinkit را از آدرسی که در بالا مشخص شده ، import کنید تا بتونید شکل لودری که مشاهده میکنید را عوض کنید و همچنین یک سری property های دیگه هم داره که متونید آنها را تغییر بدید مثل عوض کردن رنگ و غیره

امیدوارم که به کارتون بیاد.