Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

http request every x seconds in angular

I'm trying to refresh an http call every x seconds in angular2.

  ionViewDidLoad() {

    let loader = this.LoadingController.create({
      'content':'Please Wait'
    });
    loader.present().then(()=>{
      this.http.request('http://mywebserver.com/apps/random.php').map(res=> res.json()).subscribe(data=>{
        console.log(JSON.stringify(data));
        loader.dismiss();
        this.fact = data;
      },err=>{
        loader.dismiss();
        let alert = this.alertCtrl.create({
          title: 'Error!',
          subTitle: 'Please check your Internet Connectivity',
          buttons: ['OK']
        });
      alert.present();
    })
    })

  }

I get data when the page newly loads. But now my issue is refreshing the http call to get new data every x seconds

like image 986
user6579134 Avatar asked Dec 19 '22 02:12

user6579134


1 Answers

I would create a separate service to make your http requests:

@Injectable()
export class RandomService {
  constructor(http: HttpClient) { }

  getRandom() {
    return this.http.get('http://mywebserver.com/apps/random.php');
  }
}

Now you could simply call randomService.getRandom() inside of setInterval, but you can also use observable operations (there is an Observable.interval for example) to handle this for you in ionViewDidLoad:

async function ionViewDidLoad() {
  let loader = this.LoadingController.create({
    content: 'Please Wait',
  });
  await loader.present();

  // x number of seconds
  this.interval$ = interval(x).pipe(
    // make first request right away; otherwise we have to wait x seconds before first one
    startWith(),

    // cancel previous request if it had not finished yet
    switchMap(() =>
      // catch the error inside to allow for a retry each time
      // you could also use `.catch` on the entire observable stream which will
      // cancel it if there's an error.
      this.randomService.getRandom().catch(err => {
        console.error(err);
        this.alertCtrl
          .create({
            title: 'Error!',
            subTitle: 'Please check your Internet Connectivity',
            buttons: ['OK'],
          })
          .present();
      }),
    ),
  );

  this.interval$.subscribe(data => this.fact = data);

  // Separate observable to dismiss loader on first emission
  this.interval$.pipe(first()).subscribe(() => loader.dismiss());
}

ionViewWillUnload() {
  this.interval$.unsubscribe();
}

NOTE: this is assuming use of RxJS 5.5 and Angular with HttpClient. You may not have these, but you can still do something very similar. You just wouldn't be able to pipe with lettable operators and if you're not using HttpClient you still have to do .map(data => data.json()) which I would do in the service.

Finally, avoid storing and manually unsubscribing if you can, as in this.interval$. Instead You might do something like this.fact$ = interval(x)... Then in your template you can do *ngFor="let fact of (fact$ | async)" and you don't have to unsubscribe manually.

like image 178
Explosion Pills Avatar answered Dec 28 '22 09:12

Explosion Pills