0

I have the following code that obviously need improvement. It uses interval to make repeated http get request. Is there another rxjs approach to improve this code? The reason I am making the first http request outside of interval is that I noticed the interval first delay then respond with the data. So the first request circumvent the delay.

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { Weather } from './interface';
import { Observable } from 'rxjs';
import { concatMap } from 'rxjs/operators';
import { interval } from 'rxjs';
export class WeatherComponent implements  OnInit {
  weathers: any;
  response: any;

  private serviceUrl = 'https://api.weather.gov/gridpoints/OKX/36,38/forecast';
  n = 10000;
  constructor(private http: HttpClient) {}

  ngOnInit() {
    this.response = this.http.get<Weather>(this.serviceUrl );
    this.response.subscribe(
      results => {
        this.weathers = results.properties.periods.slice(0, 2);
      });

    // 5 minute interval
    interval(5 * 60 * 1000).pipe(
      concatMap( () => this.http.get<Weather>(this.serviceUrl) ),
      ).subscribe(results => this.weathers = results.properties.periods.slice(0, 2));
  }

}
vt2424253
  • 1,387
  • 4
  • 25
  • 39
  • You may create WeatherService that inject HttpClient rather than Weather component. WeatherService may be injected to the WeatherComponent. – javapedia.net Apr 10 '19 at 00:16
  • I'm not sure what WeatherService inject means. I'm new to angular. – vt2424253 Apr 10 '19 at 00:18
  • Try [`timer`](https://observable-playground.github.io/rxjs/timer/). E.g. `timer(0, 5*60*1000)`. It will make first emission immediately. – kos Apr 10 '19 at 00:19
  • 2
    Possible duplicate of [How do I make an Observable Interval start immediately without a delay?](https://stackoverflow.com/questions/44165893/how-do-i-make-an-observable-interval-start-immediately-without-a-delay) – ConnorsFan Apr 10 '19 at 00:19
  • https://angular.io/guide/architecture-services – javapedia.net Apr 10 '19 at 00:22

1 Answers1

1

This answer already provides an answer to your issue, but Ill leave this answer as it may lead to other issues if uncorrectly applied.

Refactor as follows:

import {Subscription, timer} from 'rxjs';

const MILISECS_IN_5_MINS = 5 * 60 * 1000;
export class FooComponent {
    private timerSub = Subscription.EMPTY;

    ...

    ngOnInit() {
      this.timerSub = timer(0, MILISECS_IN_5_MINS).pipe(
        concatMap(() => this.http.get<Weather>(this.serviceUrl))
        ).subscribe(results => this.weathers = results.properties.periods.slice(0, 2));
    }

    ngOnDestroy(){
      // Unsubscribe to avoid mem. leaks, as the timer stream is infinite
      this.timerSub.unsubscribe();
    }

    ...
  }
Jota.Toledo
  • 27,293
  • 11
  • 59
  • 73