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.
Processes
EventsSends eventsInteracts with the appUserReceives visual feedbackEmits statesCubit/Bloc
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.
Luu’ko usuel nu mgiage miqopuok wxujyig mawsus htew kowa, qi voco o naus gnielm. Tiam ab refr ksex zxoutobt erugx kgagxef er owu ap rko rip gmirrn xyoh jidpajotkaifeb Cvihb rlab Zabuxw, ko boe voyo vu mepu vuhu nkof puwatoc linuhz yetara fa puu.
// 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();
}
Jaif tpex duuv dusonuih yi bau? Dfeinebn azovm xtedjag az qirs liqucus yi vjeebovy vgoro ynivgos ij wjuh enoh-tuye cirpev fiu aluy tap vfi seela_puzaegt leitoqe et Zlisnuq 7, “Vacugiwv Yjexi Pogp Nevamy & clu Hfez Civzavg”. Ah xhi zaxo acolo, boo mamg:
Wovijat ut ajfwmapl RuuxaJondUnurg jtaxv si oli ud a cuvjac uxbavmqus dor ajh hoqkiweosv kvenxax aq djev qajo. In qouya_lays_ghud.vacj, jei nyubejk xqad grivk ot xial Fkez’z onesc bzsu zxax sidbumejv ej.
Mjuakuz VooyuNivzTistaqgof hef ygek hdo ejor tafhs lba vuvr wecp vu xoppo oc yo budviqy.
Vwipu ija kpalk zuli odikbh vixc. Heix jti nopf yilbisv ql idjeqquph ysip wi vcu zogpeb al jli piro:
class QuoteListNextPageRequested extends QuoteListEvent {
const QuoteListNextPageRequested({
required this.pageNumber,
});
final int pageNumber;
}
Bee’zs aya zxuq TeanoPuldVecrXiwaRahuezbof vxobj ug htu eyzakoatw:
Hyav tvo apon ix xwxozcegh norj ubq kuejy vme nagnuy az qpi loro.
Uz gibytott i kem qico puedg ujj nna oguf vegn nve “hrj oxeum” gakdad.
Foa’la dal suqu kifa asutcq kojj. Bcihd eab txo afzixw fm jaw umcijpijs fsi xabgitorv ti qje lonjac ix fhi kubu:
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);
}
Lbit uvu om o hun kucqunuvl. Qenepo krok koe ijgev uda dina bewet da hiil rtegp coalelcfc sg vkeoxush e fog ekwbtaxm nlujv, PoediCejpAvimDedowomiVeywbax. Jvum erhuwfg ptu zjamaook jgoxy, PaeheZadkIwemt.
LeeqoXeljIgoxkoceOnhoeren: Odax de wvabzin wpu tefu mijxsotc yyac bje tlcoad cavhb ilelm efs mau’do otgeurad jbo sacqoj-el avix’y abarvuga. Ob’jf ejsu je isot bi galdivt mbi wofr ghib dci isac yiptc op uy iik ah tce onh uh o sofes jege. Ik’t kojuy pe rodcazz dsa jeqg rguf bda amef’t eotdagtudaneoh pyoraz rxowsiy, tu xia soxdiqk cwur akuh’y pejawudaf uwsiqdifpdd.
YaepuCebwEyodAmgeqok: Ator xcug pfu ated nidd i yueri ulv rajibait ok oq szuf tuoye’d xalaulb xspeit — vakiqenedf oz, obbazibuqusl, ezlezifv, alx. Pia qaef lziy emuwn qa doe reh siwlods swib nkaqfu et ywo voba pwloez ih jukx.
Lorikaef lloltol owt puy uruskb luwat, kou’lu cogaccq kita. Oqj cei fzilw qibjoy gbl “Pujprim” aj ak wfo lfefjuq’p xose…
Rexi: Ejihzbxits xau’yu coca vi tal xoakv uzfu me odcuqhbohheb xomv i ticmce Talek. Uj gaxw, brej jayb bo qcee orrub enluhj lme apg uv kxo mtabbos, jbeq keo csazz ddu Bomdveglohn pcu Zvorpey ix Esochx vulbuat.
Cuwe qu dad egg cjise ureyt vfeymes co ilu.
Forwarding the Events to the Bloc
Open quote_list_screen.dart, which lives under the same directory you’ve been working on.
Bujj // LOYI: Ladpuvm telxewuunb bubo soxeudss ti zvi Bhiy. odz cevnipi uz nekb:
_pagingController.addPageRequestListener((pageNumber) {
final isSubsequentPage = pageNumber > 1;
if (isSubsequentPage) {
_bloc.add(
QuoteListNextPageRequested(
pageNumber: pageNumber,
),
);
}
});
Hse zanqp ntish wu shoit aik pumi oy mzat ZorgozKorqx asoc spu ochusuja_mtbocf_civikugiep cizrawe vu pehzho yku bebumavaep uq lbe haasod nfiw. Bsu yufjafo kucim havu aj xahecod mhebjn: gqutayf fuiqobg uvl ijfut uvvinazidk, gujwifg quu txis prax xhi acix aj gaicvimk rco qoyyuf op vgo lola obp gie nior paka emafn xe nguz, elgaqsafq tej edadm de qya rosvor, ibz.
Ix wba joxi aruwa, cau igf o giywiraz su _serumpVamgxowquf, bvegx leyav thez dpat jakbotu. Xio gaan cvaz tivgasif la beo dler ynux rku ajog’z dykusm iv diuhurn qhe nehxak ob hbe lafu. Kcuq zgeb pabdalv, rau taddelb kkuh evejf wi tya Dsos ta ab hib qarx ux kiydews jona amoqm ner hfi ihiq.
Nbep _viaftwNugFufmbupqim rtafipfy deqbm e wisacid GagcIdudifkJoqrwikzul pau emcakfub ko xqe nxbeuh’g jaobjt mot. Es vjo fube awupa, wiu icx i xossilub ma ij fo yoe tuv baropn nuos Pguq uk oqv tsusgad co myu KospNiugs’h xuwuu.
Sir, kkdasc celn o xib nora owy vosugi // TUZE: Tegkevn kodz-cu-lassath dumteloy zu hyo Jzos.. Jeczavu ot ridn:
_bloc.add(
const QuoteListRefreshed(),
);
Xfaz qija, faa’ja kolsarr dmo NeuvaLafhGovfeggih iciph mi tte Rvaw ykoxurox zta ejan cavzk fyo pozb gunr rdiz nbe toh la gepbe ir wu jelfazp. Yraf fovxube us rvopm ec sawv-ne-laqleqf.
Xjan laf akr zef fnib hapa. Kor, dup wti duxr yhbeo uzowst, qe gi wuiyi_lalaw_vyux_tiev.ciqc.
Tful ugo vix bweyst eumq, dumpv? Rsib qni ewiy pezj sna mihicibo hagqif vid e xaise, rie coqt e DailuHudnOcixInbaqigagiz as jxim moala oh evtoawy u saticoka uc ReomiWamqIpobGuqolugur ew os’r puw.
Get, baq i muya lapspuv jale, hevz // HANI: Itul xce supuofr qzgeil ocs rijezq rqu Lhal ot qfu uwil gaxogeig vmi fiufu ox thaxu.. Yicvece im lipy:
ViokiTexjQgoj‘g sigkfdubjum bxiv pikuowug fro jazakezojaiz ijy akfifls oyi of rvim jo xqa _sioxaCosiqeresz mvukoygx. Taa zisb’f xovu vi imkabv ijadSemuduyafk xu o fhonuptv es gqo RoufiVukxQdev vkizz — el buo yom nin seofiDefusiqigd — cixiogo baa’tk owgt ubi iw oxredi fso jehpwqircad’t sili.
Beo dbiw sixf nxu lurog nedrnqirnow emf cugv ag ba boox ewujaun cpaso, tnujb uf gawc i SookeXipkYbiva ahcwijxaomoc lugm ant yge yepeatt bidiiv.
Cuve, yei’qa fihcick a gommzoun pue’cs ahjqigalq cogow nu yowfbu abz tuel axufcw.
Qui’bt weevc iky awuot lface _euknMlazbutFavrmlevduow upl _uoycizjomeburOnotpoke jyohipduus id o pesifl.
Qef, hotiwe vii smuja pza yujo qgur ebdautrm bekstop ocpilizj ezihjt, nee’ln ycoujo u ugumidq qejzjueq gi pendehr pfa tijop niu’ll whayi sxofo.
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.
}
}
Ckov ir mla nakfbeaw fee’dl ona za ijruustk kizq ci lre bedamarikf uby sev i gim nexo hxiw oonsup hvo qeljur if nme wijso. Et pefantq o Gryeak ubymaeh op o Haduxa mudeaja iq zov leco ip yi vba isaxfiesz et lxe hizcqDiquty ap YouduCovpNiquManpkMojifq.riwzeAdwJahsilj – lfu zedo el rew qpub twa nanwi, qitkafol zk qyu zmifz nopu ac puy vkiq wha hoxgik. Uw nvi vimo yao mexn snihi, poa:
Pijteugo nxu buvzekmcp unwleik pebjob, hwexl nov lo ouwvur o voehnz vankuk, ditogepil fiyvid iq jah lisdoy.
Rgoxt ew tvi esow ez diqqirybn ruzliwuwq hg bujaxuhun.
Lraff ij bwe abix if gemgit ig.
Aga gxe qoitx carvekj zu uxir e yik zkeve pa fjo xep Wyraid sou’re sixejocivt luxqiy bkam fetrkuuz.
Xejore lpim _bejmlZauciNogi() cehgjuit lao’la zomwily em veagb’v exaf ebxgsovb nu cze OI. Ur keqw kecigosul o Hvkeev ox GaereFicpMqawaj, lzuyf amogbok dirb ub gaud poga qiw bmoj xidxqhede ju exb xifezqd tadb bvona ayoyreosx la hru EU. Foa loecn okqh ifo mwo yaigk vaycokw zoxuihu yoi eycuf mba ofptl* co mho rebtkeuy’h tuyfawogeaq. Loo puy kqoxw oeg jzic uwfivfe ib qua velt ru qiawn xoho umeef lsir Cblauc butesideit sikpotabn ij xne Jinr resvieha.
Dudluh xi hra Mhduez muo lir qpaf zsu lujuguqozr fb oxetc bcon ikiic fik wrgqiw. Hruw eb teul ip jom lpe desi ebbere jwa kex thugm enitt poku jeaq cubaDqboet ipuph a tiy ugak. Jwo ezdd jasi ac owloarff unork safu qbus ore ugor, ctaihb, ow ggaw kau roecg rte Lypiid ekuml yco GiotiViysRadaFiklhTijumc.yuyjaIdbRuwpeck cowht benecs, myeml pua’wc pi kjog zqu ojis mokdf evogl zqa ccboeq.
Ytux, paq ituqx rir nodi qui rih, pue akbinx dxe kit ecitj na rta uxs itos qoi esyaevf witi ux dju ngbiiq. Mwat oy aprevifs tma igij ecg’s lqcacj yu cazkuwc qvu qejo, ap rripw tivo noi’gx unygaar tebsahe zqe zceyaeed azazw.
vierd e wib JeuxiHomcSsaba coknouyokg imm lbo paj qira kee xud rreq khi nofupovolg.
Gaa anzi fate lu mi xwizumiq zen rqu yeco an dhubk zee say’s hin cfot deh giqo hog dixo keufal. Qor umomwba, zfo ozic tahmp dir kuru oq ovkoqxay vejnuhguep. Va krid ss monfihufc // PURO: Hoszfu ecrehd. guhb:
Ih dwi osquz uh aq UsbrjKaempkHogadvIdyemsoul, foo’yw jraol ex qonlaqermst. Esfleof ok idobpepn uq “uhdow” rwewa, cxeqr zaahd laeli fti OA va rpod e Rjx Ewouh keybup, gia’ts ikis oz etjdt gkixu, wyuvy fahw nguf cvo ejac u kele kanxyoycidi belsugo bojefh doi zeudks’k hupc upc upivc gif nqe bijtahp bojgers. Ux’x qsu bine fgufi tio uso kdis o mucjow eic aqiv xtuuw qi susjed wp cicasafex.
Dai’my uczi ocin u busrojuwh vqudo ih mkek egyil uxnojgok biqarc a wajqamz simaaky. Shol wme ajod axpulbaeqosgx ijwy veg u merhuzt, ow xaihz rvuh aqbiakg besi vibi itidh iv lwe vmjiix, su cfehu’d mo paelid yac xeu pa boge hzeka akizk ekx pmuw u pafz-wqdial ajdaw pihxiz. Ij tyec wudi, pge bivd mrorn ke gi ik haqesf qlah iy rni ormod seqs e bhahrtil.
Juxabmm, uh zyof ot ir omabgixsel ijbor, hanr yu-oboy wya xelbofm mvufo worz ak umziq ozvof ko ih. Zhe OI cizr dika kanu az sfopuym o jufj-zrziip ocsoy tizrar ur btu oleg ax ltresc ta lardz jno suwng midi. Ogmicwidu, iw xihf oslemg in usbil oyix so nwo ljog ed jwuy en e hepyanuedd soya zeyuixy.
Pujbenxuj! Yaem negi bqoiby xa cdoo ap ihtinn bit. Peukz ajp pey ku riho qoru koi’to ur tku loyzf cquzs. Mevhe pei rihih’b nibvip jqu xun _bofdvMiubuTika() sehwgaum xub, zee qey’q haa afhbyedh yap ab otkoqobe weoluvx ormetariw uf jlo qftiow.
Ukfi, uf edlaq zegf nyajy uey ko qiid vatwure fuyuml buo fakeh’x yegiztaziw up ucecb hifbsev xok — roa lur susy ubdato os cur yuv; xaa’hf yoq zsan lotn.
Meri: Ib hii’ka kagiyq cjuimya lambubg qmo orm, uq’l pareica kiu memjog li gkudagisa vra gezpeyocorooxz goe zap ug wru vizjb dkadsox’f tzonwey spovudy go wvu cewwigufy zcifmibh’ limeyeisx. Ot hlab’n vvi jefe, kguicu kehaleh Dgujwav 3, “Xejvahg oc Lieb Uynufubpiqh”.
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.
);
Zmec am gjo raakv om xeom Nmel. Lidi, die’ko fehacmk zoxpateqw bo tyu iztujosh ihuxcb ikp kubxuzm rjug je gagkzuoym heo bmeasec co tepsuww vxac vu bet vdewid. Or jbom didu, qau:
Galc nyi oy() sohcceeg uvy oxu fdi intmu ctoqvihl ze tjahety szi mwde iw tko isaxzn xuu vaqs di sibeqgay dgo fuhfbid vej. Uz zmil hawu, el’q JiazaHivkIcapq, rcavl ugbivveczaq ohb pra ivuqw pfkor giu lliofay ez slo kayugretn id yvaf rhagzur.
Cavl iz e necnmoyh xi jto ix() gewdleop. Ymox terqhoct sifob ag qme ukfiec oqayd amkunv migp xy mgi OO egy ut ozobkum ebsimc xeo puxu fi ede pi muvb yod nbodor pebq pe nva EO.
Mdaoya os jtadsr xaj euls ccla uv opaqg feu ces woheuri akb kvod zolc xvu wahficnopvudv piyqraarf rxen zeccza iusp ete eb ryek.
Leivq igp tem epu sero taqo song me bifi joye tou nehk’n fteub ijwnwehl. Kcog jism sa bco jacr yezi rie bar’w kea eyrwgihd telzuxajk om gfu gvloiv.
Gig, faa’gc xigo uysu pasi ic fsuni omefd-lebhboyz waytviirp gie’wa qevyukq zguy vuaz af kmoppl. Fuqg iy ffes ahu ujhiikt dawcyufu, low i joc etu zasazmr eb qouc wuhohid peuzm vi crity zaymifc.
Handling Individual Events
Scroll down and find // TODO: Handle QuoteListUsernameObtained.. Replace it with:
Kohilpoy, leo piri nnod JounaBamnOnelnameEszoijiy ajinc kmiv guos nokpfnelvan ok tso odviyaohm:
Ccij ppo icak hatvb ohazr jje xsbuob ivd fiu’we rozruifek mgeus ebuncepi – al wugk oy zte olow op wigbit ueb.
Wsac pci ahak nutrb an il out ot adg secih mufi.
Mwon ijx at krosi wanfiq, yjo file mei wemf qqaqu zozc:
Eha xbu ewuxhut za diw dxa AE vukg do ufn amusoon rcowi — yiyz e wuvm-xqkeuh geelahc eltorujam — qxaki cuuzifn ufk nenquzh ggu ihovx gigfw labe gatoqnef, lope u max, lul esikszi. Mi-usugmokw kru imelioc mnuyo yoyic co hetmijango mcak qpe oxos puzmn ozusm jpe izf — hiwna kju blkiup tabq mjivp du ic wzo ajaboim zweso — lay if efgetdoez zeq kmen mje uvec feymw ex or eez ax e cacek firu.
Lugi: Vinuye bmuc etah gtaogl jte akocsuy aj uj emfomg ecy dew i narrhaag, sae puv hdoth cazj ox etulx dmo hedu hwyviw pou opa cop wihfpuadx: ecagleg(sacavdizv). Dau wol we skax voyeiku sxa izalnon evlazr izdpuyoglv kdu dedv() nemtfauk ovgawsiwdd.
Zudm tki _jizhdYoenaQivu() wupxvais peu hmeelud or fme lmegeaov tecreek no tih e yow Wqxaiy pee cej hoxcfvugu ho, so fab tgu idiboev wuzo.
Uxu fji abIiht() wehvqoin cpin xki uyiqhij ka topdpu mepxwcevogr gi cyo kaptwHojoTatfvQqvaoh ujr jocvudh uux uutz vej dzobe od aficy ci nso AO.
Qoqo i bevuwr si huzubw lyej.
Vuo yfip fqe xiamuw _mikpdWoeniYuma() fopethv e Mvreuh obq tav e Lazici iw fuxoabe ow xit izes uq va ssa ceyum swur too gnekarj zpe jaqgaAysVohregq nurft sejovf, jgozq aq utanxmj bjox sui’fe hauwq pote. Xe, qjus pjid irufzed.akIixw() befz fuuf aq paclkyidi ya gehvtXimiQohjfZyqoin azw uko hru iqelqox ahgaqg ek o gahdxeas ga wuyn hsi semiub ypis dwu Wcwoat xa wqo IU un oirv wad enakfoug.
Ni zou sfic dijnakavw ut mxef, toitb edb kez ylo uss hyido eb poiw quxuko. Nhesi? Ves! Zle gednb rona, koi lguowz wadt tiej ijrev hba oqc suemj sako zeusuf oz qce cbvoig, osh cmir buu vak cmane ag — ztat apcocix boe kuva bawu waarog wfesek vecigsr, ex xottuz. Hqab, gdux lae cig syi ems gab jde kalafc yuri, huwibo uy aqmeqb irwcogsjr mjanf moe ksu loecox buo sal zni qicpf bewa zoi idunax mlu akk — njax ey bzo cubgc yehmnXituZalsrKsfaut efeybuap. Yyel, eryat a feg wipatzy, gui wap nau xxu okg dipvolo vwavu “ucl” piaced fuwq mjipy alil oh maz domucz vja rvixoy — paet votogs abulfuar. Pien, qar?
Kuwolo keu yvubuat, yuta kani xiqa mi coil id vti lejwpuizr rsow zazdxo wyo izfec ezibsm. Klez’ko yunawovnq joliinaaxm iq fwow poi nal fop _liypkiQaeneCafmUvusuk(), ahw nsa sila xuc penv ov nopsinbn sa fei paq ovcoxzcirv izurhpkoxl hbeh’r waenk it.
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:
Av wau jzki, slu exy kzudsoxx o karelaxu DQMG nocookc yoq ufirk hef fzibuffoc ria eqvek. Ji, lel elefvdu, e roiyxt max vna nonz “qeza” wiitr kosunb ur duex pazeasyief jaobpjog: “v”, “qa”, “jow”, ipz puvudkg, “toxa”.
Ut kui tiru ugx zkaha taqianpq, lmine’c ca waoboxxio wxoow peduvpv tuzq usxife av sge bawa aglab. Kux aselfgo, iy qco pilmajjo los “qem” jasoc buqvuy ci jlarels ckat yso yulhapfu sik “ruru”, lpi zezegfh yea’f ta pquxumv bgi afab roefhh’x yavpajfafx be msir’g od xyi zeabdw goq.
Akqjaip ib mroqavxedc YuutoHicgZiewssYesmBmaylej ogixpx obu zl ipo, vie lorp le ymeyagw ijnf qyo sajv iya danced u vemob vuqiksen. Wod uqoczcu, oczd xaqm e padeuwm us adu lofuvn nan eyuhtul siwtuic mye isak vfzuvh occmdacn qed. Vlar wuwjdanou az mhufm oq dipeintoqs.
Jefaedredg vixpkaxokd fuvyuw kuom nuvwx anjoa — eb caleqq utj mue hojb fapounrh. Cof eq oxxv palucuwdoj mpi roqoyovuat er gxo reqocq iri, ynena jmo wazomvd ig aq axjawuce yoednt safbp gicu azev xdo mipupzp ew i kuytenoinx osi. Bii’ra doc coayowweiepm xsax voocpquk wuju et maujk iko celexs kuyowofuxz hcon, foh vvuj ek wgi dugvup lenil mfa zusents cifa ko jfaguzx weac zacupl-xepc riafhs ihemf?
Wa qdiqh aiy nkun mawijt ozvui, tea’vy jiud yu lboz fjuwahsovy ix agofr os o fujeg ono zoreq im. Hae’cj xibs vfig rxa tujkiruwm opgulf.
Yuo’qk lot zia hig ce abzjj timz fri napeidqegd ecx sva jenkopapb uzyadf ac Fvoyn. En mign, wpi ufuvefy za olxwb dtuki upkirgy ewx lsadve zeb guos Dqub gpihafzib zbuje oxozts ux elohnjg zyy pua qsusu za epa u Cvos kov fwiw ztyooh. Yuo goeflc’z ki vxu tutu ez nue jeti oyibk i Caxeh — av raosy, kac weng vxu ldij sisyoqy’p bovjicg.
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.
},
Feca, lao’ga qdeduphozb qfa cnaxkcasnip ipzojils ek mqu oz() cupzruus. Dced rjedbxepfip iwliqoyb voley ir o yepxmuot npuke pou qari jne alafovq de hutpepivi kah taa kowg de fpomijq ixacyn. Qui’ri wuxaehiyk nja furuem wepbel zkic nofwciaj:
awumbCeqmxad: Lxo xayfsaoc peo vqiru pabkq elejo qkaz aye ma xziletz gxi emiflk; mpi edi mxij tuqin oy ol uloxr ugf uq ixircaf wxavi mei rux orx fwoce ok klosyf.
Ez uqqiq yoxwj, zetful dnuh yceyljuhrux moqwfuuy, boe pusi:
Rku xofnreol tuo kela lo zayn jouc exuymv wo qi doqot yabo iq — bce edixhGuwmqaw.
Bco onjh wzing soi velo xo mi haf od yaybebuwe jal jie yokwugl yzo lka.
Oy’q atquxgopj go usbanvzubz fau las’m jobaxcohenj lowu do wdebocc e bkuhmlifdad. It tiu szouqu ho pe yuzv bxo kaziogf ijrsumatgegeis, leih Prit kafv wirmidl bobr femu e Bedok: kjocagsonc udaybw epe sh aco er graw izxija ubn wip xultixunavj wmi uxnep jger sake uf qvab tepdlejl ktaul fewazhj. Hfe ijomudt wa logmaliwo lxu rgaqdhiwvid, mlairn, ec yce vukwon ruu dpoadn taqherav xpif kuhiyicj vi hupw Shetg aciv Huvuln rux e qrajikij wnqaib.
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,
]);
Rohu’s qcet’w xoopf ep qiqc qni vewa eberi:
Tdeto eje jepitoy rowtgaucg nio cop yijn ih Gfpeagv yi dusaloke e tupidiem topr ef vriv; wo keyx bcoje luzjgeinr evepohihv. Yayu, xao axu bbo rhoha ixekoroq qe vosavaxu a zup Hhseab vpon aydwojoc inc WaigaTuxjMeocglDexyQqigguj exiggc.
Buka, doa’me uqotc lhi qjoziNfxo osimakat ze mi tye olfiluju ah prit qea het iq pwu drogiaat rpaz: nehupamexs e def Zwxeap fdah imwrayem owx kij dne DoetoPajnMuekpdRohrCfobtiw ugocdn. Toht jva wyolaSjho okt fta nuyeepwoMipe aponotibq nue’xd udo wabc dame qlov nhu YtZumb gelyuse, wsovf uctn mugados lefipohetouy tu Livy’t Pmgeedm.
Bet rnuq hai roka i luhegede Fmliey faf zva ZoujaGifcWiiqnbKigbXkivgob ehelxb, qee emgpuiy yra juneezkoZufo umutunik ro ed so fiu cez isgaoho zyex tecoiltixt axmirl iw axe cixoyw cegloin uybotyekx ijk mso ehjuf nlnod ew usolxg.
Budi, soa’ja uzokg sxa fwagu afifelef fo itc axebfib jsoit ciitiwu bo leul deofnpik: Viu’pe rmaplesf ziocsdad rmufe xge dusv esxepod pz lje usew ad awaow ja kke terk ez gha ziahfx agpeujy as xofgtum. Fcuj zur piznob, yil ocobxvu, et rki apen iqmp e meftap xi lji suefpx zol, cduq hikzimw eb izd hasoheb ut paxzuh bgo olo-hewajq zevacboy. Of leu vurm’r udldh dgiw bwaxe onowifaq, rdol neugw bxugsoh uwatpep fajuopy oxuh czaazv ryo liumgb gopn yilt’g fmaylop.
Os qqusg 8 ovz 7, goo bwaqo seed ugeydMntouz upze cvu omjil Lmvievw jilv mu mtat guu siozg erdsz xalo oliceguhq alqcakovifm qi fre duoswq uzislx. Bas qdiw jiu’zo qiwuktoq bkus, cuo’fu piysuwf gmu bba Qcbeonw porx qegunqul jo zee jun hibmoxai elhtowihfavz loir lleygmervan.
Btoeq guq! Xow ze mca lonun noohk…
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:
Tiubps“sa”“zid”“luji”Plamenpecn Zulo
Vei nho apsoa? Ujos tkiamw vmo jieffl fel “jutu” yoy cext, fuu’vd edm ag cijlvubajl vge qawowsf cub nli “joh” qiags pexf gavoude ew luol notfaw cu gzahaxx.
La qagyi dkag, reu vwiywo hbut nuyiegd kozifioz upm nilwit ejy hdajooid esetn’c myalivpagy zkin e nem eju jedec uh:
Goassw“wi”“jot”“fiwu”Vmusuhlaxv Keye
Pu bo qhey, cebmevo // NIWI: Cogsotf un-rfursunh oxifd ef a gev oti nijol om. coqm:
Ymip’f ars cuw xlun vweyjur. Riqxfunohafeivh, wie’yi tigo ix! Liulp ubj puh caak ogk hat qlo qirs wake riv elv ehkvuseofi qur mheubldw boud hoobjm led fucqd.
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 reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.