angular - Duplicated http request in ionic 2 with async pipe -


i new ionic 2. using ionic v3.6.1.

notice http request fire x times, x request bind post async pipe. so, in case, http request fired 3 times.

kindly advise best practice.

provider:

  getpostbyid(id: number) {     return this.http.get(`${this.rooturl}/${this.posts}/${id}`).map(res => res.json()).take(1);   } 

ts file:

post: observable<post>; ionviewdidload() {     this.postid = this.navparams.get('postid');     console.log(this.postid);     this.post = this.data.getpostbyid(this.postid);   } 

html

{{ (post | async)?.id }} {{ (post | async)?.title}} {{ (post | async)?.content}} 

the share() operator

everytime subscribe cold observable, executed. 1 way avoid behavior make hot. can using .share()operator (which shorthand .publish().refcount(), more informations these operators see further) :

returns new observable multicasts (shares) original observable. long there @ least 1 subscriber observable subscribed , emitting data. when subscribers have unsubscribed unsubscribe source observable. because observable multicasting makes stream hot. alias .publish().refcount().

ionviewdidload() {     this.postid = this.navparams.get('postid');     console.log(this.postid);     this.post = this.data.getpostbyid(this.postid).share();   } 

quirks conditions

if use observable first time in template , use once again inside element appended conditionally (*ngif), might experience trouble observable have been run , no new data emitted.

for example :

template :

{{ (post | async)?.id }} <div *ngif="post|async">     {{ (post | async)?.title}}     {{ (post | async)?.content}} </div> 

ts :

post: observable<post>; ionviewdidload() {     settimeout(()=>this.show=true, 5000);     this.postid = this.navparams.get('postid');     console.log(this.postid);     this.post = this.data.getpostbyid(this.postid).share();   } 

here shareoperator (alone) not sufficient because post emitted, ngif condition becomes true children async pipes subscribe observable has emitted value. renders :

mypostid <div></div> 

there 2 ways workaround situation :

  1. .publishreplay(n) : operator replay last nth items emitted observable. combine operator refcount() keep track of number of subscriber , reset cold observable if there no more subscriber.

    this.post = this.data.getpostbyid(this.postid).publishreplay(1).refcount(); 
  2. using *ngif="post |async mypost" syntax introduced angular 4 (or maybe 4.1, can't remember) allows store result of pipe inside local variable mypost. explainations here. can keep .share()part in ts code , end such template :

    {{ (post | async)?.id }} <div *ngif="post|async mypost">     {{ mypost.title}}     {{ mypost.content}} </div> 

2 words publish() andrefcount():

publish() transform regular observable connectableobservable. kind of observable start emitting data connect() method called (it makes observable hot).

from the docs :

rx.observable.prototype.publish([selector])

returns observable sequence result of invoking selector on connectable observable sequence shares single subscription underlying sequence.

refcount() method available on connectableobservable, role call connect() method on first subscribe. called again if subscribers unsubcribe , 1 asks subscribing.

from the docs :

connectableobservable.prototype.refcount()

returns observable sequence stays connected source long there @ least 1 subscription observable sequence.


Comments

Popular posts from this blog

angular - Ionic slides - dynamically add slides before and after -

minify - Minimizing css files -

Add a dynamic header in angular 2 http provider -