1

I have problem with polling some data with the GET request from the API. I would like to poll data every 1 second, up to 30 seconds. The point is, that angular seems to be performing requests (it is logging response), while in fact it doesn't perform request to the server.

I wrote following methods in my service:

private pollStatus(token: string, remember: boolean):Observable<any> {
  const httpOptions = {
    headers: new HttpHeaders({
      'Token': token,
      'Remember': '' + remember
    })
  };
  const url = 'auth/status';

  return this.http.get<any>(url, httpOptions).pipe(map(response => {
    console.log('polldata', response.status);
    return response;
  }));
}

public secondFactor(token: string, remember: boolean): Observable<any> {

  let pollData$ = this.pollStatus(token, remember);

  let watchdog = timer(30 * 1000);
  // this.http.post<any>('/auth/login', {}).subscribe();

  return Observable.create(subject => {
    let pollSubscription = pollData$.pipe(expand(_ => timer(1000).pipe(concatMap(_ => pollData$))), takeUntil(watchdog)).subscribe(response => {
      console.log('secondFactor', response.status);
      // some action based on the response is performed here
    });
  });
}

In the component I am calling it like that:

public ngOnInit(): void {
    this.authService.secondFactor(this.authyToken, true).subscribe(response => {
      console.log('response in component', response);
    });
}

In the console I can see that, subscription of the get request is performed multiple times (code: console.log('polldata', response.status); is executed). Unfortunately only one request is performed to the server (verified on the back-end and on the network tab).

Output in the console:

polldata pending
secondFactor pending
polldata pending
secondFactor pending
polldata pending
secondFactor pending
polldata pending
secondFactor pending
polldata pending
secondFactor pending

etc. etc. etc.

I checked this behavior under different browsers (Safari & Chrome) - same problem.

Work-around:

I found out, that if I will send some POST request to my server (commented line: // this.http.post<any>('/auth/login', {}).subscribe(); in the secondFactor() method), then Angular start to perform GET requests more then once.

Maciej Treder
  • 11,866
  • 5
  • 51
  • 74
  • 1
    `console.log('polldata', response.status)` is logged multiple times but `console.log('secondFactor', response.status)` is logged only once? – frido Feb 09 '19 at 22:07
  • Both are logged multiple times. – Maciej Treder Feb 09 '19 at 22:27
  • But then you're getting a response from the server. What is `response` when you log it? – frido Feb 09 '19 at 22:44
  • The point is that I am not getting response from the server. Angular doesn't perform any request (I can't see it in my server log, as well in the 'network' tab of the developers tools). – Maciej Treder Feb 09 '19 at 22:47
  • Do you have any HttpInterceptors or service workers in your app? – frido Feb 09 '19 at 22:53
  • If you're not altering the response or caching the data yourself with HttpInterceptors or service workers try to specifiy additional `no-cache` headers as in this response: https://stackoverflow.com/a/44561162/9423231 – frido Feb 09 '19 at 23:06
  • @fridoo I tried your proposal - no difference. My problem is not in the response itself, but in that Angular doesn't perform the request at all. – Maciej Treder Feb 10 '19 at 10:31
  • For reference, a similar question has been asked: https://stackoverflow.com/questions/54369125/why-are-my-interval-polling-requests-occurring-only-once – frido Feb 10 '19 at 19:18
  • Try adding to your URL a random param per request. Can be a time stamp or any random string: ...yourUrlPath?timestamp=5395384 (Force check it’s not cache. This happened to me implementing the same logic on mobile) – MCMatan Feb 10 '19 at 19:56

1 Answers1

0

Can you check please whether this would work:

public secondFactor(token: string, remember: boolean): Observable<any> {
    let pollData$ = this.pollStatus(token, remember);

    let watchdog = timer(30 * 1000);

    return interval(1000).pipe(
        takeUntil(watchdog),
        concatMap(() => pollData$),
        tap(response => console.log('secondFactor', response.status))
    );
}
Amir Arbabian
  • 3,419
  • 1
  • 6
  • 12
  • Unfortunately no difference. As I wrote, Angular is "executing" the GET request, the point is, it seems to return some kind of 'cached' data instead of perform request to the origin. – Maciej Treder Feb 09 '19 at 22:27