Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to slow down / wait before call to my api?

Merry Christmas to you mate.
My Angular 4 app will not await.

I want to slow down before API I call.
but I just continue to hit a wall.

I'm using a HttpInterceptor in my code.
but these Observable will just explode.

To not get too much contempt.
below you'll find my attempt.

export class ApiUrlInterceptor implements HttpInterceptor {

    constructor(private http: Http) { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return Observable.create(observer => {
            setTimeout(() => {
                observer.next(true); //Not sure why I do this
                const start = Date.now();
                console.log(`Request for ${req.url}`);
                return next.handle(req).do(event => {
                    if (event.type == HttpEventType.Response) {
                        const elapsed = Date.now() - start;
                        console.log(`Request for ${req.urlWithParams} took ${elapsed} ms.`);
                    }
                });
            }, 1000);
        });
    }
}

The result is that API is called.
but no result to caller is installed

My Observable seems to be stuck.
and I'm running out of luck.


I'm well aware that this is an anti-pattern in Angular "don't wait for a random number", instead structure your application so you do not need to. My actual use case was that in HttpInterceptor I need some stuff that is loaded by other Observable, normally I don't have troubles, only if users refresh a particular page I had a risk that the stuff was not loaded.

My direct taught "quick fix" was heck I make an if and if not loaded I wait for some ("give it time to load") then I proceed, who cares! the user will not refresh that particular angular link often. I ended up the long way move all to a config.ts and use APP_INITIALIZER. However, still, I want to know how to wait for some time if I like to wait, hence this minimal example.

like image 762
Petter Friberg Avatar asked Dec 21 '17 15:12

Petter Friberg


1 Answers

Do not despair
Instead here have a glare

import { timer } from 'rxjs/observable/timer';
// or import { TimerObsevable } from 'rxjs/observable/TimerObsevable';

export class PreRequestDelayInterceptor implements HttpInterceptor {

    constructor(@Inject(PRE_REQUEST_DELAY)@Optional() private delay = 1000) { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
       const delay = timer(this.delay);
       const start = Date.now();
       return delay.switchMap(()=> next.handle(req))
       .do(event => {
            if (event.type == HttpEventType.Response) {
               const elapsed = Date.now() - start;
               console.log(`Request for ${req.urlWithParams} took ${elapsed} ms.`);
            }
        });
    }
}

By using an InjectionToken you can inject a fixed delay. If none is provided, 1000 will be the default delay.

like image 52
Jota.Toledo Avatar answered Oct 19 '22 13:10

Jota.Toledo