Angular. IsLoading = true

Создал обертку для отлавливания loading и error в шаблоне. При загрузке страницы все работает корректно. Как сделать, чтобы появлялся isLoading: true при нажатии кнопки Reload? Код (пример) находиться тут https://stackblitz.com/edit/angular-ivy-adrsnn?file=src%2Fapp%2Fmain.service.ts Спасибо.


Ответы (1 шт):

Автор решения: Андрей Харитонов

Сложное у Вас решение. Так вам придется везде добавлять app-wrap, да еще готовить для него inputData.

Для этих целей лучше использовать Http Interceptor. Это перехватчик всех запросов. С его помощью можно обернуть любой запрос перед выполнением и любой ответ после выполнения. Например, его можно использовать для добавления аутентификационных данных в запрос или для парсинга ошибок формы после ответа. А в вашем случае можно вызывать глобальный loading и отображение ошибки.

В app.module

    providers: [
        {provide: HTTP_INTERCEPTORS, useClass: ApiInterceptor, multi: true},
        ...
    ],

Для самого interceptor ApiInterceptor вы найдете кучу примеров для оберток запросов и ответов. Перед запросом нужно в каком-нибудь LoadingService поднять флаг, по ответу нужно этот флаг опустить. На этот флаг подписать компонент app-wrap, который будет в одном экземляре в app.component. Я рекомендую в подписке в app-wrap добавить debounceTime(1), чтобы значение отображения маски Loading не происходило во время работы ChangeDetecting.

export class AppWrapComponent implements OnInit, OnDestroy {
    loading = false;

    private subs: Subscription[] = [];

    constructor(private appData: AppDataService) { }

    ngOnInit(): void {
        const sub = this.appData
            .subjMaskLoading
            .pipe(
                debounceTime(1), //Надо увезти подписчика из того же тика, потому что все это может выполнится в ngOnInit() компонентов
            )
            .subscribe(show => this.loading = show);
        this.subs.push(sub);
    }

    ngOnDestroy(): void {
        this.subs.forEach(sub => sub.unsubscribe());
        this.subs = [];
    }
}

А для отображения ошибок можно было бы в том же interceptor добавить CatchError в pipe(), который бы показывал всплывающую плашку с текстом ошибки и дальше бы пропускал ошибку без конвертаций. Мало, она может еще кому то пригодится. Вместо плашки можно и модальнцю форму показать, используя dinamic components.

Конечно не на все запросы нужна такая реакция. По примеру @ngx-loading-bar/http-client можно игнорировать запросы с каким-нибудь особым header. Interceptor может улавливать этот header, понимать что не нужен Loading и обработка ответов, убирать этот header из реального запроса.

Кстати в @ngx-loading-bar/http-client как раз сделано через interceptor. Это самое логичное решение.

→ Ссылка