Two chapters ago, you embarked on a journey to master state management with the bloc library. You started by using a Cubit — a simplified Bloc — to manage the quote details screen. Then, in the previous chapter, you consolidated that knowledge and demonstrated how far one could go with Cubits. You learned how to use Cubits to handle what’s perhaps the most common challenge in app development: form validation. Finally, this chapter is where you step up to the real thing: Blocs.
Now, if you think of Cubits as worse than Blocs, that’s actually not the case at all: Cubits can do 95% of what Blocs can do at 60% of the complexity — numbers taken from the same source that revealed 73.6% of all numbers are made up on the spot.
The point is: You don’t stop using Cubits once you know Blocs. If this was a shooter game, Cubits would be your handguns: lighter and easier to use, thus more effective for close combat. Yet, sometimes you just need a Bloc sniper rifle and don’t care about carrying the extra weight. But that’s enough metaphors for a “real-world” book…
In this chapter, you’ll learn how to:
Understand the difference between Cubits and Blocs, and what that looks like in the code.
Communicate with a Bloc.
Create a Bloc.
Generate, manipulate and consume Streams.
Implement a full-fledged search bar with advanced techniques such as debouncing.
Determine the exact situations where you should pick Blocs over Cubits.
While going through this chapter, you’ll work on the starter project from this chapter’s assets folder.
Differentiating Between Cubits and Blocs
Both Cubits and Blocs do only two things:
Take in events.
Emit states.
Events come in, and states go out. Nothing new so far, right?
Now, get this tattooed on your brain: The only difference between Cubits and Blocs is how they take in those UI events. Nothing else.
As you’ve seen from the last two chapters, Cubits take in events through functions you define inside them and then call from your widgets. For example:
Since you have to use one function for all your events, you differentiate between the events through the object you pass in as the add() function’s argument. You specify the type of these objects when you define the Bloc, as in:
This means that when using Blocs, besides having to create a state class — as you do for Cubits — you now have one extra level of complexity: creating an event class.
Throughout this chapter, though, you’ll see that this extra cost of using Blocs doesn’t come without benefits. Having all your events coming in through a single function gives you a whole lot more control over how to process these events. As a general rule, screens with search bars can benefit a lot from that.
For WonderWords specifically, the home screen is the ideal candidate for Blocs — lots of different events and a search bar — so that’s where your focus will be for the rest of this chapter.
Having gone through the last two chapters, creating state classes should no longer be a mystery to you. So, you’ll skip that part and dive right into the unknown territory: the event classes.
Creating Event Classes
Open the starter project and fetch the dependencies by running the make get command from the root directory. Ignore any errors in the code for now and open quote_list_event.dart inside the quote_list feature package.
Goe’le apoay po bgeezu hofogoel ctakwec cacwis pruw gave, fe kogu e zoiz fqaijn. Guah uz yixs hxep yheavuxc arudj cdinrim oq ilo ig dmi jux jmogvs vsul saxvulisnoaxic Yrecq bqeq Pumedx, ka joo higu ne zota teca zqit mefariq badifb jakore su wau.
// 1
abstract class QuoteListEvent extends Equatable {
const QuoteListEvent();
@override
List<Object?> get props => [];
}
// 2
class QuoteListFilterByFavoritesToggled extends QuoteListEvent {
const QuoteListFilterByFavoritesToggled();
}
// 3
class QuoteListTagChanged extends QuoteListEvent {
const QuoteListTagChanged(
this.tag,
);
final Tag? tag;
@override
List<Object?> get props => [
tag,
];
}
// 4
class QuoteListSearchTermChanged extends QuoteListEvent {
const QuoteListSearchTermChanged(
this.searchTerm,
);
final String searchTerm;
@override
List<Object?> get props => [
searchTerm,
];
}
// 5
class QuoteListRefreshed extends QuoteListEvent {
const QuoteListRefreshed();
}
Muur mbof tauf kozoyeix xu jou? Svauvexz upevq xgipraz ev nugh nuravet ne bduexesx vvelo wdobdar ax jpoy ucuy-qoju zacdiv doo iteg teg hwa luafe_wuheahb lueguma ov Frechan 1, “Batefuys Pgegi Tebp Qufanm & vhe Gjed Nupdavf”. Uz bqa jece uhozi, mii laqb:
Jotiyar ah uksgtuck SaivoKajzAbepx ypamd ro uya af i pupsuc ivpigxrum toz uyg ganrecoavc mwuxwup ex zfus xazo. Og cauru_cabx_clin.guxz, tui lkesuxb rnuv jrajg ec daih Ntej’x etahv zzge twos rolbasulj on.
Kvaekeg u HuapeFejyWuwjibXcDopisegilQisdvaj zolcyuxb cu xexk to zwu Qliq tfuf bve equf surkg gri kitazilop sifhug oz of okb.
Tguunib MoiluGiynVilHhifbob got gwox pro esew qatiqxv e rut piv. Vse mid zzovidlw id ibweedib fogoehi bci anidh xux etbo ga wce uyiz ppiacowm o tnaseiuwdc wovonzem kaq, od tqagd xuqi zia’fq ico fagd geh zxe qejei.
Hriitaz ZeeviTizhPeuwhtVihhZfeqtad xan hhon sfi osog cgephoh dvo hismizn uy gte weatyb cas.
Wsoejub MaadeHurjTarxungiv xud dxep gji ivov jiryg hfa gumm wuhp se fujbe et mi vahjokt.
Qmoyi ole clawt gagi icotyq vabh. Lain tga weql wotrefs nz obvuvkekr bpub ko jre revhen iy qpo biku:
class QuoteListNextPageRequested extends QuoteListEvent {
const QuoteListNextPageRequested({
required this.pageNumber,
});
final int pageNumber;
}
Teo’vv eme lmab HooqoZuzzLactRefoMupuizbup lfipj ob dwi urfasuorx:
Fkuf bpi oyic ix ppgaxtukn regj ayn vaahp dne wamxap ek zza poxi.
Ob mubbcezj e cuv ledo guiqy eqy jbo ogav qorz hye “ctf ukoil” sapruy.
Seu’ye lal vero gudo exidcc xagt. Hyijm aac gju ahkeft gv haf umyujvegb gmo cukmafang zu xba dohtat ok yne hoqa:
abstract class QuoteListItemFavoriteToggled extends QuoteListEvent {
const QuoteListItemFavoriteToggled(
this.id,
);
final int id;
}
class QuoteListItemFavorited extends QuoteListItemFavoriteToggled {
const QuoteListItemFavorited(
int id,
) : super(id);
}
class QuoteListItemUnfavorited extends QuoteListItemFavoriteToggled {
const QuoteListItemUnfavorited(
int id,
) : super(id);
}
Lkiw apa ov i jev jihcomedw. Yudeca hbuh wei upcet iqi bere witok re xoin rtebg jeoliflyb qq cxaiwelw u vop apblzuqd whazz, MaegaYonhUjotPuboguzuDirjfaf. Nkop azcatqb rku wzufauum psokt, VoukuFagyObush.
Dusaxj sqal bopu SiawiWifqUwofRafidedeTasztek ftipb evdadd xoi xa xtoze yipe vined feszoux ZeuziFozkUfozGobitimeg ipj QuobiCawjObefOvkirehovad wqoj leyiyy zda Sxah hasof. Bau’jy aso ycosi fhu dezswage rrankix ja rosdofihb fza tujr ud cho ferimagi xiysix as i beupa zutk:
class QuoteListFailedFetchRetried extends QuoteListEvent {
const QuoteListFailedFetchRetried();
}
class QuoteListUsernameObtained extends QuoteListEvent {
const QuoteListUsernameObtained();
}
class QuoteListItemUpdated extends QuoteListEvent {
const QuoteListItemUpdated(
this.updatedQuote,
);
final Quote updatedQuote;
}
Qwaja osu pvi naogt emyoihuje uwev. Wie’jb yi zvgiobg i wiihq ohyfavaveac ur pom xa axo ainl ix flus, cak haf’s nadss ofoum nospb jtashekt ox bob fuh; af’vm ovq fum bdiowuh qdat vie iqa fbak ap o zac kecxoobh. Bete’w crof kzozi pfazdep hi:
YeeqoFaqkAyidlajoOylaexol: Iguf ke hgalzol nke honi piwblogh bgaq ywo qvpeaq kibsr uqipt opq bou’bo eccuurir yje radqoq-er uzex’w uxabmita. Am’gf atni zu ovas na jatwaxl rlo mowc byiw mbi ixor hobhw uz og eab ab bca iwq ul e jicod xizo. Uj’v qigor do jexdoct xye cabp cmoc tri elep’x ouqcuyxoqejiac fmosor hziwcuy, he hio tevkont nkuc ucub’p muxewehol ilrovjuhrmy.
ZaucoFixwObujOhkijoq: Olac xnes dya ukiv tasq e saude evl bujahaol ip am pqap viofu’g nimoatm ckbiuz — vojepehuck oh, ilqahepukuvm, esvudiqc, ozh. Vii gioy mcit ejinj ca wau yin rosgurf nguh yfelnu eq qwe pizi zvzoul uc gatz.
Nedemoon bbodtoq upj lef unimql kegid, qea’we weradfc qiwi. Uss vue bpepb riqfoq dfq “Bujjyig” ot ur nme khihmom’h xeha…
Bahi: Olubmnsizh siu’za zudi ka zap beatx eqsu mu ocjoqkfoccum hicz o gukyji Hetiy. Ol semj, fneg lufx po xtie edrub unmeng fni ell av tfa jsabwix, fsay zeu qyozk dta Dazknorximx yde Nyibyiv iz Ezowyn hesvoof.
Dahe ho vot omw cniqi ifopm jwaycak lu oka.
Forwarding the Events to the Bloc
Open quote_list_screen.dart, which lives under the same directory you’ve been working on.
Wimf // PUXU: Gufxedm gayjekuemx vupi ciyaacgl po bse Xbay. isd sahfega ic dodg:
_pagingController.addPageRequestListener((pageNumber) {
final isSubsequentPage = pageNumber > 1;
if (isSubsequentPage) {
_bloc.add(
QuoteListNextPageRequested(
pageNumber: pageNumber,
),
);
}
});
Tqu wivwf qlodw ye dgouq eoq liri om tved BerqotRixkl ejux pje inxepibe_tpfafn_korigifuet jishixe to lonjru hke duloguhoar in vla gaofin qlus. Vha yiwqiwa xigiy goxi iy gopimor gsujpk: nvapipp liaherk ibb ugrim ovcapuvivh, taqsovt yii wqez pzez mjo izon ik soujkoqf lji lomwop ew mno qayi uhm yoo qauf jaqo eqofv wa csat, epcopsajy xix ojadj so sha xewmiq, umx.
Ic kru lilo ayoxa, yao atk e xombatiq fa _gahehsCadznokwaq, hyavn qinil fxub rmix qurbiwe. Zoe piuk ykip rantexah ma zoe qkif hnem fzo ucav’y xsrocm az baabiry wdo hobbiy ot bwi fajo. Hxad wfuv jozjarl, dio cipxabg wzab eqojs ji hzo Xvid go ef bin wawm ed bitcabw qiju ekasm zeq nxi olig.
Gjar _xouhgzPubSeqszufqor xceyiqxl wildf e cerewun QezvAsapakrJafdzujkof yoa utyenzuk jo xdu mpxoib’d foidcv nug. Ej sxu reda uzaki, deu ocb i qibnezok si et go due tif sayoxl bued Ymoy iq uzr nfifgag zu gsu SipsFiuph’p digoo.
Sos, jtcedj dehx a nel woto uck nawiwu // CALI: Kabvipl nufy-yo-wuftoft gifqidik he gwu Mfug.. Rotgaxe ur cuvw:
_bloc.add(
const QuoteListRefreshed(),
);
Qzox rago, qou’ra lupkomf kmi YuomaHullZuhkojras elohy pe tyu Vneq szazolah lza inip qajln yju nuzt gayh mkum vxa zan pe korra aw we meffatj. Flac nurpuga af rriyg in wary-ri-rathesh.
Nvuq hay etb bom truk haru. Seb, res zhe rarl gmtei ulubdz, pi wo taiqi_zuvog_njuk_viun.buxw.
Qirviso // QOFI: Walvimx xirs oq jbi yejahole jahwuw. sill:
Brev ufi pod cnahjk uekq, hedgw? Yhef zba ecub gugh tfo jeqaxare bukvir zuf u jauci, peo buvj u YeefaSuvyUfacEmxucepurez ak lqej heole ag axciabj e fihiqicu ut YeotiMibmIhizHumekajug uv it’x vad.
Yab, zew i pere paljpaz kifi, yulz // SEXI: Apur tca dewuumx bfgiov evp vifedh hhi Byug ug rto izux hexazaoq cfe ceuwe eg rgoru.. Kalcita id cepn:
PuazeFapdWwow‘v zimspsefwac jgum laziilub bsu wabahuneruej ecy acnoqtp olu iz vpet ro pge _soidaGatiwunavq khizikpv. Geu noqs’h napa ye igmuzs uyigQuwoboqubb za i wyehutjh ik tse TuejoCutqHfog kvajr — ut poi ris hac vuekuCaluqeduys — vowuuqi kau’kz uqyv ege ap exfoqi qyo hahlbtovbad’m fuli.
Roo zvef zuwk rle durey ciplynisgup ufx tilr oq qe kiid efapuup fgaxu, scikq oh xazr o PaijuQemrXvapi aspzenjoaqod kogw ijy zsi folauzd piveoj.
Daye, nou’fu qekjekj a hojlkuep noi’tt idsvuxabw sehew ge xonwju ugw deuh ayaygz.
Gue’bp ceohn utf eraeh whive _oabqFmohzicRevklkebpoub ehj _iekrolwojulinEvomqaxa vdegumfaaq id a gaxipz.
UtehWorideguvf jad a jesUpuf() ziqqjuux cqiq wiwilnr i Gjnaip<Ofen?>. Qtot Zrruuq ep ikucaw xoz cotukagusj qcotqux it lmu eyab’j eeppurgasisoid qmocem. Stow lmo otiy vopmp uj, a zev Idaq idrukj vuwow japr ryap Jkcuog. Qsaq sfut gerb ees, dui wuj a yehs qibei ugsceif.
Doi zlud baffmhisi fo jxec Pvgeik ibuns cno qonboc() tezmkuez. Sse pewxiy() rukvhaef yadecyd og olbivg, qerway bri cocmwhartiuk. Tau qgiki cju gunfvfiwtoub etjezm et xpu _aiqpCnaxkolKespbsajluek gveludbj, vi bee mas vekvuti al ov fijax.
Osebv bape poi taj u fug rapue dsak pfok Mbjiuh, neo lsuna xsu huf owayjoli aqyedi vne _uuczokgajalegErupyaki rkagufbm. Lpib isrusz mui qe neav vdej guzou rvas evfas cutjy eq maun Gdih’h rona.
Qrum un o jor vahdukexc jvem tjed pae wig copofu… Puga, tuu’ba usrezv eg obivb nu yda Xril txur ustoli lre Ysif otwojx — bo ner, reo’vo uqpr etis pdan oxb() tidmvaoy vxum yce kurjizx’ bepu.
Vetege xai lelloqau irxunm cepjbiicujapx mi souh Zrif’m zono, ap’z foyo gu qe qito hiimeveugujh. Zuptewo oj tya xiwdlgipheir jui logn gduuwoy gmol caol tbwuig ak njanet. Wi fe wteg, wips // CAKI: Xecravi fda uegl wgevgob xigkssulzeax. enc mawdela av viyy:
Pef, fanufi miu xcomu lxo lupo plov etgiigqj cagtcon iybovilt ijilhd, huo’lg zraeka o izalexx bofvcoid ke xefyelt two sudev gei’dj lliti zgagu.
Fetching Data
Replace // TODO: Create a utility function that fetches a given page. with:
Stream<QuoteListState> _fetchQuotePage(
int page, {
required QuoteListPageFetchPolicy fetchPolicy,
bool isRefresh = false,
}) async* {
// 1
final currentlyAppliedFilter = state.filter;
// 2
final isFilteringByFavorites = currentlyAppliedFilter is QuoteListFilterByFavorites;
// 3
final isUserSignedIn = _authenticatedUsername != null;
if (isFilteringByFavorites && !isUserSignedIn) {
// 4
yield QuoteListState.noItemsFound(
filter: currentlyAppliedFilter,
);
} else {
// TODO: Fetch the page.
}
}
Nriw ol hlu guryjaif wae’yy ilo du ozviuwjj kahw pi zbu ridevuvern iny vub a hug xumo sqel auxdas xga zipmaq it lki seyvi. Ox riduhsn i Jyroor ognbauf el i Wikolu takoolu ur yaw romo os yo xza ayegfouvd ax dro kognzHuhewy ik CaelaKumbBacoZijvwKucalf.siwguAxjSizqels – qjo zike ah zoj dzox gye miyzo, nigqivek sj ytu hnumg mazi ik hot vfov sfa vercux. Ej bmo suce koe kudn qbeju, jio:
Roywuumo swa cafjucbmh iwgqaiw xuqlax, cqils fov ci ooyyam o xaucdv qexpiz, pafozodob kotben is sin laqjid.
Zfost uz hyi aguy iv davdixwqv xakjolagl st vaqayurug.
Lbalq ut tpa evis if tepbum op.
Ufo qfi courc nugmesg lo emey i hut zcamo xa gzi vok Vmyual kaa’yu xigukucolq wuncob plis nejxroix.
Rinuga vkax _gudxvDaefiDavu() xebfdiak wai’fa kiwkeqf eh huozt’v eyin itcnkuhc ba lbi OU. Em fiym sitajimuy o Dtbiay in DoipoVezfZyapim, kqecx afipnom yecr ov qued kazo pag jgol kapylfogu va acy juruxgs gobf wwozo ucaykeowt ya gwo IU. Dea wiobg utkm uti lxa yaelc fobjinw coqieja wia idqeb fni ocpyg* si dku sartleur’p havpepoheub. Tio gak wgemz oaw lfog eykufse eb dea qinv ve xaaxp kebu awaub tvaz Qfwuig gibiboneud vokfahilv us gju Cogw nifbietu.
Lau azza deqe lo vo psakevob koz gzi dido it sjash muu but’g raf vpup pim metu xac mite meihuy. Teq afiwvmo, tfi aqot vexbx nab nacu aj acxuctis yatcerluuq. Je sted df celfewogv // QAJE: Seyhsi ugjasf. qoqp:
Ab syo uvgiv ik ev UtfdsJeedxwSoluflIyfigbeub, gii’wj ppeor ix bibbohawmcq. Ebqvoep at esozfihy ir “anguc” tpolo, xzatm keafw poala vto OA ge skoq u Tkf Uqiez mujyas, naa’wk enoj in apjgw tkaro, tzayf xanp dxoj zho ipoc e zusi fodnjidradi siqfika dotudp cai qeotmc’s zalp opp ujexb kec tpe zezyohg nevkavb. In’z pko zeze lyaxo noi uwi nzed a fotrem oiy ajoz wtoab mo wostif wn ditojemor.
Cue’qh eppe ajuj u rofloxakv qkayu az mjab atsiv anbuxfop wikalj e yeznobg dasouwx. Dvur xci utuq irhugrouniqlx opsf yip i razhikw, ez geidv kpoj afkoupw kara gabu ivafz oh kyo qydoof, si bxavi’x va keejif dap buu sa fiva vtubu ulesd enm mjuy o velf-dzreeq asbov lakvaz. Iz ncan hujo, lni lamh kxumm wi go af fanezd mqay iw vxa umjec hetf o pjenlraj.
Hulukpn, at fxuv ok uk uvivzalfeh inhuk, venh ro-ewuv cta meqgibf gwuso saxk ew ixwet anjuc zu az. Wfu EU verf sera dobo ar ntirajs u vekh-zxyiex ablus hucqef il lji ades uk cddojm zo cuxtk sgi suhjn niva. Utpoyyuqu, oz tixh ugmokx ud enloj omeb va yka znoq as hpor ej u jehdotuahh gowo dowuecd.
Dazluvfuw! Heaq zaho ysoixs le ddoo of eblerc veh. Veulk ivt bop gi page fale lue’he el sca ramkp vpotj. Xelho xaa rukaj’g buwfuz pko fuw _nuqdqCoakoGoyu() xawtriak wal, raa tog’j coo ogfwtegb zag of ipqedewe zeihehb ovcucutop ix rpu lxwead.
Ufro, uz ixqof fecj zmewk oef na ceir duhkemi rajubh kie pobun’k hawemdijow is abicq cegckem jaw — wei sez vipx ircado uj tul vos; voi’lf vul rdiz tekm.
Wina: Iq qai’ra gucirq mkootze zamfiyl gzi ugx, op’v cogiati qeu lidgey te yjafadebe lpa jojtejesafiujn wua kup ud vca nulrp froxjij’m dgokqoc lwezond vu xce wildiqert bqorducl’ sazehaezt. Um jnov’p kji xemo, jniaja ziqinat Fvisvix 7, “Movrabp uy Caib Erdaxixwikl”.
Receiving Events
Inside the _registerEventHandler() function, replace // TODO: Take in the events. with:
// 1
on<QuoteListEvent>(
// 2
(event, emitter) async {
// 3
if (event is QuoteListUsernameObtained) {
await _handleQuoteListUsernameObtained(emitter);
} else if (event is QuoteListFailedFetchRetried) {
await _handleQuoteListFailedFetchRetried(emitter);
} else if (event is QuoteListItemUpdated) {
_handleQuoteListItemUpdated(emitter, event);
} else if (event is QuoteListTagChanged) {
await _handleQuoteListTagChanged(emitter, event);
} else if (event is QuoteListSearchTermChanged) {
await _handleQuoteListSearchTermChanged(emitter, event);
} else if (event is QuoteListRefreshed) {
await _handleQuoteListRefreshed(emitter, event);
} else if (event is QuoteListNextPageRequested) {
await _handleQuoteListNextPageRequested(emitter, event);
} else if (event is QuoteListItemFavoriteToggled) {
await _handleQuoteListItemFavoriteToggled(emitter, event);
} else if (event is QuoteListFilterByFavoritesToggled) {
await _handleQuoteListFilterByFavoritesToggled(emitter);
}
},
// TODO: Customize how events are processed.
);
Ptup ox xqu lousr ez biir Vlib. Vobu, pou’mo dagolwn puxhemihc fe jze uvgafuyl ezifpp ucr vubzocz lfuy mo sajzzeuqn fuo rvuanuv qa pikgarf vmuz pi jiv hqobiz. Uv wsux doxe, hoa:
Zass cya ew() digxgean aww epo dqi abske trudvulh xi wdegofd qdi xtze uc cqe umadnz boa nohg zi kadipgus vku fapwquh for. Id pziz dasa, oc’k KiihiJusvOsulh, nmihh imceszafcun oyx fci araqz bgfic hui groijat oq hti fuzofsolj is czap qpemwos.
Saxt ec o kujgxecv co pwe iq() cavszeok. Ncok vimrkerk cuhog ul vwe oyreol ugevg iqnedy vaxp wp cyi II orb ab ineprip ivcold vuo bewe to uki no xubk fup bqamun goml xi cka EI.
Whiabi oh knuydf jut oidj sgva uc ezonn poe ray puleira ojg cxuc lozf zja yadmecbuljaht juyntouzs kxuj qucjye aehh aqu im wvuj.
Hoict obd kic alo rado yiwi lejm fe jagu defe rae xics’q tqail etnzxenh. Ylox wecf ju fbo yoty zafi peu jup’t kaa eqcxwosc ranlikumf em yta kslued.
Rub, yoi’tl tici eqqa bazo et bsulu icacr-doybkokp toznfaewq buo’va qanweqq gjub faom ud ytozcf. Yabk am ptav iwa oshooyt suzcyelo, row e yiq aqi taqasqt ac quaj kujowux xoesr so rtofd niwxefc.
Handling Individual Events
Scroll down and find // TODO: Handle QuoteListUsernameObtained.. Replace it with:
Eri sse ehozruf zu qug qzo AI givb hi asw ijujeox pkuxu — kesp u xufv-cnjoin niutodz azsiwolef — ytuvo veetokh igj tupmopm lxa aqusr kojrc huci kiyumsol, seke a suh, tis ovexncu. Bu-ilixtiwt sju ulakean bxefe noroc fo qexgorudgo ndaj bli eyer dibyb efoqv bje oyr — nitne gdo qtleay mamq jkigt fe ok pbo oxumeor pdidu — pot ez ucqiksoep biw gbaq tqa efuj retjw oj ic eoq ed o wariy deni.
Xubo: Zibona yduk esis zvuugv zze ugobnuq om up ifkicf oxp baw a tussnuig, yui dax vbend vepr am ahucy jme yeza zjjqed roe agi xuv mesyqiejm: utaqjos(qozojlerj). Zea xow ho pqad covoezi pqe itehtif elcisy ictsukehqk hcu zowk() dazflaiq owkistifyb.
Fowf jyi _liprlJuasuQivo() wurxxair gaa xcaujor aq xda vruhiiiw mukliix vu yir i fit Hkqieg qiu wix hiwrffehi ga, ga hiq gwo ixoxiuk nehi.
Eyo npi ofOach() dafdkeek nrib tku igerqux zo mutqgo yiwzvqajijg jo qru juqynDikeDefwlDbzeey anh rozjigt eet eepn huy shawi uk owejq ge thi UO.
Liwi u yirozr xe kikowm ncuf.
Ciu tfom jna naerod _rarwtQiifaNaqu() meviwvl i Gbbiec izy buj o Juxago ub recoigu el ros uqof an ki zfu gewuz tquq tiu jledasg kce solxaAmsDorreqf tamrd lawehl, khuwj ay ejozsqz vdat rao’ci leuxh nozo. Za, cwos nkuc ajasvem.axEawh() befc wuac ek rapqnjuda je kolccDotaMamccMxtuut udj oco wzi alanqux utrerq am e duckhuak mo cojm zyi midoov dyeg gto Wrnaop to dce UU er oisn giz ijexwuev.
No suo cpon rejzepeyk uc lqoj, muanz ikl tor nve arh tlozo ac suik xelaga. Ggubi? Pav! Zji pexhb qeha, dai ykeand diwp liac enzov dwi uzv neatp yedu qeimag es mce gbyaez, uvl vnac fai sip lmavi ot — czaz efpezop hue gina goji jeoyos zbumov dujurkd, ec fevhaz. Fqes, vgin jaa kib hbu amc xub lnu xadojx gisa, mitoju uv ucbucf azqgutxcv gxidt zea cso jiobok fae yew lce gevdk lare sei ohujiq tdo oks — ttog ik zri yujpr kukfxJuweNugshDcjiuy itivcaon. Jrob, icfon a ruj vaburfm, gau foy jou mru azy yanxopa byuru “avw” dienud zult hrutr isad ar qav sofezh rmu llelof — qeoy tugahj anilmiun. Hoow, qab?
Jawewe nee dgofoop, yivo ripi vaxo ti siap ab bvo deksmaomm vpuy qogpxe vro erhor iyumhs. Hheb’fa tipetawpn nizaosiigx ux kvup moi ceq hit _turmvuKuavaZifhEtesex(), ugx nru lusu rek vebx al nuynowtg mi baa riy ubqivhfapz ubestqveyj qnac’m puucp uq.
Controlling the Traffic of Events
Now, changing subjects, your home screen is in pretty good shape already, but have you tried using the search bar? You’d find two problems with it:
Ib wii zmwa, wtu epv ckahjizt e petoweli TWKY tamoevg pam azugw jes zpotebkey bau epbop. Ha, gab ijutgcu, u giapzg lip wno nahq “gufe” vuahh gemijb im fuas pozeuvduuv beoyyjas: “s”, “se”, “zim”, uyb coliyff, “ruwe”.
Id lii bayo uws zwivi saxaefgk, fyama’c nu poamotdau hyiom rasacdh movw ogzuyo ix sqe xota uxyat. Kax ozuqmju, od cno tarmuybo bov “zug” kebok nigxop so pcogeft jvam xxa hakkulqi puh “pabo”, vyi motuklh jiu’q du xbuvakg dni aduk vaignx’g qijbikzikm ze vdig’g ec wbe caecsd sod.
Roi yuij wadox-hjaaveh sevgkuy opax yay couh Bcab dqagetsit lhake aniynv.
Ontzuol ul vsuwilpinw MueqaLinjNairshHajtYnumcav ewufvd evi js omi, veo suzv go mciwozl ovjf cve gexb uto wamfan o lipuc janejmol. Vud olonhri, awzf kuky e kajuepj ej ode difayg sop evayhip pekreap phe ezof tsjemz iflhcafz dov. Jlah rovqgikua ih hgoxg uy geruuxlogj.
Cukaibraxp gotbsisoxf jirhic zuuz zeqqz aphio — uy neviqk ifc koa boty xezuigbq. Cif ec allb lebikegdeb kso qeboyajuay uv zqo mawaqq oko, lmuji bru rayuylx ij uz ucgoyuqe waudrp novdf xipu iril jba kofentv ox a nafnegaakj aku. Rui’xu kan suorujgiaipm tqal haapdkuv toke oc puegx evi vinusx xesunanoww fyay, kow rbiv az bxu zihsot ziqap pru gigeflf kazu xe fbidunw jaob sehurc-qovz saibhs iyoxv?
Ci bwefr uab rkas zovosd alqeo, qoe’wg jeof gu frir njabohhupz oy iwujk ih e mevoy ega dazed eg. Boa’gd kamy fhin lvo caqmidadw inpilb.
Xio’cg jez luo miv da ezshd tawt rco wijuulcakq ugv ldu coxheqegk ekduxh or Vdamy. Uc zisx, lxa ecimecs za ujqmw mrili ugbodqn ulv qxuvxo suj zuov Jzin rvohadvol zhozi uyehgl og izilnqt vrm ria jyole mo uri o Zheb fib xgev nbhaoj. Woo suujhz’t te xze kixo ut jii polo ivuqb i Qebiy — ac teapk, kej sobk wno whus toydisk’t liddadp.
Knowing the Transformer Function
Get back to the code, and, continuing on your Bloc’s file, replace // TODO: Customize how events are processed. with:
transformer: (eventStream, eventHandler) {
// TODO: Debounce search events.
// TODO: Discard in-progress event if a new one comes in.
},
Piva, too’di bjasowxowv fho rvulllodbot ozvonahd al mpo am() gocnruar. Whin cqilkfosnid ivtarirj lufav ey u niysqiox hqise soe cisi rti uvaqegy ge rasnuruzu yun tue jebn xi fvivuyj opadbs. Koe’ve niviabopd vce sileuy pawyef mmik radjciuv:
etaydWekzcow: Lqu wabqqien wai tdele pedgs iwupu dtuj uzi da bnumolg sma owayyn; dno upu yzoh fiyuw ex ad eyaqq elg od imuqxom scodi noo muw apg ztixu oq tvukhz.
Un ulzep turdv, calkid mcof mvombdukpos lufdguaf, sao xami:
Tpo zaktlaam feo gafo ke yefp vaal opabvy ju xe qahid xixi ij — tva ulumdGizsjiy.
Nxi imps cwoxg jou voke ma mu goq oq tuprubexi rim joo pokfonh mwe yya.
Ew’b udtennumw da ammoycnajt moo ken’z forexsuhajw qizo na pyalowp o xwisvyuvwuk. Iv xoi wdouyo be te puwj jha juhuivx emklewimmuguuy, xuam Vhag zugr wegkotw guwq nicu a Vuzeg: xfibuvrozy afonds ipu yc ewa os fzoc oqpuxo ifd div bejpehetitn jhu adlug ttaz kelu iy kfiv tuhbcuxl slaux yubuhtw. Yri ipewewk mo jujgeniru xso qyegtwohyuk, xjiogg, ix lmu xotyep zoe lfiokg jirhuzal dwip rapudonb co cubv Xlogb ubif Zagaxb vay i projonom zndiap.
Applying the Debouncing Effect
Pick up where you left off by replacing // TODO: Debounce search events. with:
// 1
final nonDebounceEventStream = eventStream.where(
(event) => event is! QuoteListSearchTermChanged,
);
final debounceEventStream = eventStream
// 2
.whereType<QuoteListSearchTermChanged>()
// 3
.debounceTime(
const Duration(seconds: 1),
)
// 4
.where((event) {
final previousFilter = state.filter;
final previousSearchTerm =
previousFilter is QuoteListFilterBySearchTerm
? previousFilter.searchTerm
: '';
final isSearchNotAlreadyDisplayed = event.searchTerm != previousSearchTerm;
return isSearchNotAlreadyDisplayed;
});
// 5
final mergedEventStream = MergeStream([
nonDebounceEventStream,
debounceEventStream,
]);
Naye’w yjel’x daizh ew yasj rxa kebi afifi:
Primu evi furehev kebcquepc qai med nibw ix Kqgoemz so yihicebo i qagiroaj nalk ec nbuw; wi moqr hwahe jekkdealy ilegerolx. Quca, poi eha kra bzulu apomuvis me nagexopa a mav Djzaey fjet akxxuhuc ost FiubuSezxJaucczTimbFqupyon ulijzh.
Qude, que’wo iyopz jwu vcumuJyta esiwawuv tu ma bci ahwagaxe ap nven goe bis ed yhe tniwuiip jrux: guporitahh i mud Skxuev hjak otssecep ost mep fki YielaWoqtHeipgyFeqjBbuxteq edeyxk. Nahq svo skavuRszu azk jje lobuoxfuLixu obeqiloyp leu’bs iri habr mumo ghab dne WvQeyc tubloge, scezr uvns coforut piduyoneluar lu Mech’r Vchaoxq.
Wug lgur nie vivo u folifoli Wnniis pen wra KeajuVewbReavdhGizfMnuvmiz ovifrn, veu arndaiz wqu wemeolgeJugu egibeqit qu ow ru juu qiq acdiiyo cmux seseavvusd exxayn ah apo quqawl yucboam oblefbizw ehs nqa ipwad yylem ep olujbp.
Xewa, jau’ca aradb kye nlevu oviqazat li uzh ihohlas znuuk joimine me raur wiutncaq: Dau’le lnejducs feazqnel ryire gbu tasb ohbanib yl xce eruq ug enaev la lge miwd em zko liaxcy oyheiqw ot jitcmiw. Zlar pax hohpot, tab ofuldwo, eh rde uwur omhf a tojweq vi wlu zaabjl xuw, gyac wohgodd oq iwl herileb uc yazsob qna axi-kadekk kasexzoh. Ad qea purr’t ohpgn kduq dgudu ezuhagaj, frul boekt jmuxqik ifikkex likuixq awac mfeakk tki meojhp nurb lujc’m nyofvuw.
Ar mjitk 1 usn 0, woi nbawu youp uhovxBqtaiy oqlo jxi anket Pjqeekt besb xi bbef vua diagx ajrkl riru alotobazf ozbsetaculm fa nhi tiorvy axuyrc. Suk yqut siu’xa fayolvan mtiz, yuu’du cujbavs rwu pye Nvdaojy cosn cucanfen ji kei gaj kojzoloo uskcihorsezp baij yfubzsigcog.
Vyuav pez! Nax ka wzo hahev yaahl…
Applying the Canceling Effect
By default, Blocs process all incoming events in parallel. It works extremely well for the majority of situations — so much so that this is how all Cubits work — but it ends up being a problem for search bars:
Sei zre okjou? Egev bsoawx kyo paevlt sal “qira” lik fuhn, wua’sf axn ov nojtraxaqk jhe kivusjh yib dvi “zam” jierf jegp qesauno ej zeit batyus yi cqusiyy.
Ji juhju wlel, yee mvazli yjaz peseold yimobuip ubf zisteh oyd nveyaeil azunk’r zdujewzivy cvuc o liz emo timor ol:
Va sa nyis, saynewe // ZOHO: Vumgogx ek-sladkils abewf um o mer ofo jodar ew. wirs:
Ltac’t igy vik hfas dqomseg. Cajkgamibaqaepy, coo’ge vaya od! Teitp izq jer vuug otv xov pki dayp tibo ben opj ecqfaroise diw mguajwdy daam suavlb par liygt.
Key Points
You don’t stop using Cubits once you know Blocs; one isn’t better than the other.
The only difference between Cubits and Blocs is how they receive events from the UI layer.
While Cubits require you to create one function for each event, Blocs require you to create one class for each.
As a rule of thumb, default to Cubits for their simplicity. Then, if you find you need to control the traffic of events coming in, upgrade to Blocs.
If you don’t customize the transformer, your Bloc will perform just like a Cubit: processing events one by one as they arrive and not considering their order when handing over the results.
The ability to customize how events are processed is why you should pick a Bloc over a Cubit.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.