Anropa REST upprepade gånger i Angular (5)


Jag behöver skapa en tjänst som kommer att konsumera data från en långpollande REST-tjänst i min backend. När jag anropar denna tjänst väntar backend tills den har data att skicka eller tills timeouten har gått ut och skickar bara ett tomt objekt.

I Angular vill jag ha en tjänst som startar när applikationen är helt laddad, och som kommer att köras i bakgrunden och skicka data till ämnen som jag observerar.

Kan du berätta vad som är bästa praxis eller visa mig exempel på hur denna tjänst i Angular bör se ut?

Här är mitt försök men det anropar inte vila vid start:

@Injectable()
export class PollingService {

  private url: string;

  constructor(private http: HttpClient, private fooService: FooService) {
    this.url = 'http://localhost:8080/api/poll';
    this.startPolling();
  }

  startPolling() {
    this.http.get<any>(this.url)
      .map(pollData => {
        console.log('poll data', pollData);
        this.fooService.mySubject.next(pollData);
        if (pollData)
          this.startPolling();
      });
  }
}

Svar #1

Anledningen till att du inte får några data från tjänsten är att du inte har prenumererat på den.

Ett fungerande exempel skulle kunna se ut så här:

startPolling() {
    this.http.get<any>('url').subscribe((pollData) => {
        console.log('poll data', pollData);
        this.fooService.mySubject.next(pollData);
        if (pollData)
          this.startPolling();
    }, (error) => {
        console.log(error);
        // stop poll or use exponential backoff polling
    })

Dock är HTTP lång polling medioker nuförtiden med koncept som server push, ett sätt att implementera dem är genom webbsockets.

Svar #2

Din PollingService bör endast fokusera på HTTP-förfrågan och låta andra komponenter kalla på den.

@Injectable()
export class PollingService {

    url: string;

    constructor(private http: HttpClient, private fooService: FooService) {}

    startPolling() {
        this.url = 'http://localhost:8080/api/poll';
        return this.http.get<any>(this.url);
    }
}

Din komponent:

export class YourComponent implement OnInit{

constructor(private pollingService : PollingService,
            private fooService : FooService){}

theMethodYouWantToConsumeTheService(){
    this.pollingService.startPolling().subscribe(
        //If success
        (pollData) => {
            console.log('poll data', pollData);
            this.fooService.mySubject.next(pollData);
        },
        //If error
        (error)=>{
            console.log(error);
        }
    );
    }
}