简体   繁体   中英

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

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.

Use Observable.interval :

import {Observable} from 'rxjs/Rx';
...
constructor(...) {
  Observable.interval(30000).subscribe(x => { // will execute every 30 seconds
    this.ionViewDidLoad();
  });
}

OR inside your ionViewDidLoad function:

Observable.interval(3000)
          .timeInterval()
          .flatMap(() => 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;
            });

Edit to answer your comment. From the Rxjs docs:

The timeInterval operator converts a source Observable into an Observable that emits indications of the amount of time lapsed between consecutive emissions of the source Observable. The first emission from this new Observable indicates the amount of time lapsed between the time when the observer subscribed to the Observable and the time when the source Observable emitted its first item. There is no corresponding emission marking the amount of time lapsed between the last emission of the source Observable and the subsequent call to onCompleted.

timeInterval by default operates on the timeout Scheduler , but also has a variant that allows you to specify the Scheduler by passing it in as a parameter.

Basically in this case it would be the reactive/Rxjs way of JavaScript´s native setInterval() function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM