简体   繁体   中英

How to Set an Inteval on Angular 2 Http Observable Request

I made an Angular 2 service that successfully gets data from my server. It has one function named getSinglePowerBlock . The goal of this function is to setup an observable to make the get request to the given URL, and return one of the powerblock elements from the JSON property assets.powerblock[] . I know this works successfully, because I can get it to work in one of my components. I have included that component, for reference.

My Goal: I want my code to make the get call continuously, once per second, using the interval function from the rxjs library. Then, I want my local data to update with the data from each poll response. Basically, a polling solution.

I imagine it's not hard to do, but I'm new to Observables and Rxjs and I just can't seem to get the syntax correct. Feel free to offer a better way to do the getPowerBlock function or the way I'm calling it. I'm sure you're much smarter than me at this.

I only want the polling to be on when this component is the current page being viewed by the user.

The Service:

import { Injectable }     from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable }     from 'rxjs';
import 'rxjs/Rx';

import { PowerBlock } from './classes/power-block';

@Injectable()
export class ServerCommsService {

  private pbIndex: number = 0;

  constructor (private http: Http) {}

  getPowerBlock(): Observable<PowerBlock> {
    return this.http
      .get('/database-calls/getdata?type=powerblock')
      .map((r: Response) => r.json().assets.powerblock[this.pbIndex] as PowerBlock);
  }
}

The Component that uses the Service:

import { Component, OnInit } from '@angular/core';
import { Observable }        from 'rxjs/Observable';

import { PowerBlock } from '../classes/power-block';
import { ServerCommsService } from '../server-comms.service';

@Component({
  moduleId: module.id,
  selector: 'power-block',
  templateUrl: 'power-block.component.html'
})
export class PowerBlockComponent implements OnInit {
  public title: string = 'PowerBlock';
  private powerBlock: PowerBlock;

  constructor(
    private server: ServerCommsService
  ) {}

  ngOnInit(): void {
    this.server.getPowerBlock().subscribe(
      pb => this.powerBlock = pb,
      err => {console.log(err)}
    );
  }
}

The JSON returned from the server:

{
    "assets": {
        "powerblock": [
            {
                "id": "001",
                "name": "PB1",
            },
            {
                "id": "002",
                "name": "PB2",
            }
        ]
    }
}

I don't think so its wise to call an interval on a returned promise/observable but if you are just returning the data (not observable/promise), you can do this inside the timer in angular2. It will continuously call the function after 1 second

import {OnInit, OnDestroy} from '@angular/core';

Create a subscription holder variable in your component

private timerSubscription: any;   //just to hold the reference

You can initialize the timer in your OnInit event and get the subscription back in your variable in order to unsubscribe later in OnDestroy.

ngOnInit()
{
    //start a timer after one second
    let timer = Observable.timer(1000, 1000);
    this.timerSubscription = timer.subscribe((t:any) => {
        //call your getPowerBlock function here 
    });
}

In last, just destroy the subscription as its no longer needed.

ngOnDestroy()
{
    if(this.timerSubscription)
        this.timerSubscription.unsubscribe();
}

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