Reputation: 577
In Angular I usually have a special class which is in charge of the progress bar. I can intercept all HTTP requests and routing requests like this and it even works for GraphQL requests:
loading-indicator-service
import { Injectable } from '@angular/core';
import { Router, NavigationStart, NavigationCancel, NavigationEnd, NavigationError } from '@angular/router';
import { Subject, BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class LoadingIndicatorService {
loading: BehaviorSubject<boolean> = new BehaviorSubject(false);
constructor(private router: Router) {
this.router.events.subscribe((event) => {
switch (true) {
case event instanceof NavigationStart: {
this.show();
break;
}
case event instanceof NavigationEnd:
case event instanceof NavigationCancel:
case event instanceof NavigationError: {
this.hide();
break;
}
default:
break;
}
});
}
show() {
this.loading.next(true);
}
hide() {
this.loading.next(false);
}
}
loading-interceptor-service
import { Injectable } from '@angular/core';
import { LoadingIndicatorService } from './loading-indicator.service';
import {
HttpErrorResponse,
HttpResponse,
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { finalize } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class LoadingInterceptorService implements HttpInterceptor {
constructor(private loadingService: LoadingIndicatorService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.loadingService.show();
return next.handle(req)
.pipe(
finalize(() => this.loadingService.hide())
);
}
}
Is it possible to intercept HTTP GraphQL requests in Vue globally like in Angular so one place and one class in charge of this functionality? Because for now, I need to check loading
for every request in each component and there in each component control the progress bar.
This is how I was trying to do that for now but apparently it doesn't work this way. I thought that $apollo
is a global variable which controls all queries from all components
progress-bar.vue
<template>
<div class="progress-bar-component" v-if="$apollo.loading">
<div class="bar">{{this.$apollo.loading}}</div>
</div>
</template>
<script>
export default {
apollo: {}
};
</script>
<style>
.bar {
position: fixed;
top: 0;
left: 0;
right: 0;
/* height: 5px; */
color: white;
background-color: brown;
}
</style>
Thanks in advance!
Upvotes: 0
Views: 572
Reputation: 138216
When setting up your VueApollo
instance, you could pass a watchLoading
hook that watches all queries:
const apolloProvider = new VueApollo({
watchLoading (isLoading, countModifier) {
loading += countModifier
console.log('Global loading', loading, countModifier)
},
//...
})
The property is documented in Smart Query options:
watchLoading(isLoading, countModifier)
is a hook called when the loading state of the query changes. ThecountModifier
parameter is either equal to1
when the query is loading, or-1
when the query is no longer loading.
Upvotes: 1