mllm
mllm

Reputation: 17458

Periodic reload of data from server in Angular 2/4

I want to create an efficient mechanism for reloading data from server, for my Angular 4 app.

My service:

@Injectable()
export class MyService {
    getData(): Observable<string> {
        // return observable for fetching data from server
    }
}

My component:

@Component({
    selector: 'my-component',
    templateUrl: './mytemplate.html'
})
export class MyComponent {
    myString$: Observable<string>;

    constructor(private service: MyService) {
        this.myString$ = service.getData();
    }
}

My template:

<div>
    <p>{{myString$ | aysnc}}</p>
</div>

I want to be able to reload data from the server periodically and emit it to multiple subscribers (components). Since I do not know how much time a request to the server might take, Observable.interval() isn't good for me, as if the interval is less time than the time for the request to return, then I'll have a problem of sending a new request before the previous has returned. I guess I want to block the emission of another request until the previous one "resolved".

What should getData() return so that I can achieve that?

Another requirement I have is to not send requests when there are no subscribers, and restart the periodic requests when a new subscriber subscribes - is it possible using .share()?

Thanks!

Upvotes: 0

Views: 411

Answers (1)

user3468164
user3468164

Reputation: 45

If I understood correctly, a solution to your problem would be to wait for the request to finish and then do the new ones? If that's the case you can use concatMap. With concatMap every emission will have to wait for the delayed previous emission to complete before the next one.

Here's an example:

let a = Rx.Observable.from(["data1","data2","data3","data4"]);
let b = Rx.Observable.fromEvent(document, 'click').map(x=>"asyncData");
let c = b.merge(a).concatMap(val => Rx.Observable.of(val).delay(1000))

c.subscribe(x=>console.log(x)); 

Here you have a stream of data being emitted every second, and every time you click you get new data. This new data will be added at the end of the stream every second.

So you would get something like this:

  • second1 --> "data1"
  • second2 --> "data2"
  • (mouse click event)
  • second3 --> "data3"
  • second4 --> "data4"
  • second5 --> "asyncData"

Did that help?

Upvotes: 1

Related Questions