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 share
operator (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 :
.publishreplay(n)
: operator replay lastn
th items emitted observable. combine operatorrefcount()
keep track of number of subscriber , reset cold observable if there no more subscriber.this.post = this.data.getpostbyid(this.postid).publishreplay(1).refcount();
using
*ngif="post |async mypost"
syntax introduced angular 4 (or maybe 4.1, can't remember) allows store result of pipe inside local variablemypost
. 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
Post a Comment