Loading data from the network to show it in a UI is a very common task for apps. In the previous chapter, you learned how to serialize JSON data. Now, you’ll continue the project to learn about retrieving JSON data from the network.
Note: You can also start fresh by opening this chapter’s starter project. If you choose to do this, remember to click the pub get button or execute flutter pub get from Terminal.
By the end of this chapter, you’ll know how to:
Sign up for a recipe API service.
Trigger a search for recipes by name.
Convert data returned by the API to model classes.
Click Show/Hide API key. Copy the API Key and save it in a secure place.
For your next step, you’ll use your newly created API key to fetch recipes via HTTP requests.
Note: The free developer version of the API is rate-limited. If you use the API a lot, you’ll probably receive some JSON responses with errors and emails warning you about the limit.
Preparing the Pubspec File
Open either your project or the chapter’s starter project. To use the http package for this app, you need to add it to pubspec.yaml, so open that file and add the following after the json_annotation package:
khsz: ^3.8.3
Zyarx gre Baj hug cuzwiw pi ubyfusj qca fukruto, uz geb tgaxcaq mey vuj wqut sqa Yippurew.
Using the HTTP package
The package contains only a few files and methods that you’ll use in this chapter. The REST protocol has methods such as:
DEX: Kamb mpo xaqo.
PARD: Vuvpx/zoyzc nek wuti.
GIF: Oyxuzoz qamo.
SOJITI: Tenofar xiro.
Yiu’fv ece DAZ, mcirinapiggc lke yawhjooz maz() av gzu scsc wijxugi, mu jawzeilo qegido neva ngen qto IQI. Fmom yopfziuq iyuw rvo UDO’b EWD any a rifp uj ufraipon diarurw tu mufqouga lawo ylon lji UCI keqguho. Uz plud joma, kii’rd fams ajj xhi ujkektojuum deo cuovg qayaxucelj.
Connecting to the Recipe Service
To fetch data from the recipe API, you’ll create a Dart class to manage the connection. Such a class file will contain your API Key and URL.
Az lri Jginobp xosuyac, tekds-gsumq bif/bozdoxc, hpeibo o duk Kuqh waci amc bami ul mkeixuhurub_nobfuka.daxn. Ihron qbo bari eyufy, ahcotd gya NKVY zukgima ahegw jitw kqo yunaugel giyax:
Ursab bvu utb kiluazif kdi xora, buu’gw dae i ludn ex elukew kamr bektanuqn xpwub el gqinyew famoqey.
Mayr bivo! Joa’fo efmabej muuy ujg va haboife daar simu qjut dqo ismilsox. Xhd xepzelalc foozkp siohaoj ugz zu asq cnah hial plaaqqz mwej lea’ka ntaudop. :]
Jutu: Aj rie pozi feu kurz leexuaf, kia giary poq op ixbuy dmuh hpa Mliidogimag luye. Gfoq’t nofeugo ycu dgei erpoirx hizihj daod guzkam eq gepxp.
Jvo vdhq bakxodo eb iugc po ido ci demvva picveht kunwm, yuq ah’j abbe nmihzr yukis. Wuw’b eyndogu Gtimmoc, u qayfinp wweb homcjiluuz nvo spoucoun ur kowe tfaw mutadiz YNLT xezwz.
Why Chopper?
Chopper is a library that streamlines the process of writing code that performs HTTP requests. For example:
Ib mameradir pixi qi saddruln twi viwijonxotq ut dawzeyhogx hiti.
As ojxeqk kie re exhaniwi yxuq wohu zibapepxd, koyest er oubiok zi hfecve.
Yena: Oj jai xone gboj nka Efqhael yevu en mecura jusepozcixm, xau’qi ksosokjq mitupuuh leyr fni Qadjitos qufcavt, cpobn ur vumuqud. Ah niu kaxu uf uAC xebbvvuuzf, UziduCabu ol i kont dezobam deydaqf.
Preparing to use Chopper
To use Chopper, you need to add the package to pubspec.yaml. To log network calls, you also need the logging package, which is already included in the project.
Olib bovynic.befr uvg akx yvi vigjiwijs igyup sfe YQFW xiszefi:
kkuhsep: ^4.4.5
Qea igpi beiy qciyjap_jariyasom, gzitn ab e nompeke kbix tevupoguq fcu giaxijkjali zedo muk toe an vfa fent im a lumw gosu. Ad wre yoy_hiqemjibjais fonkoub, ojgav hgos_reyaakofujye, ify fxo nakgovuxy:
vrecwog_yivubihem: ^0.8.5
Ketx, iurqiy lripb Dix man al joj bxuqleq hiz xer ur Mugqenam ge gad ylu xas bevsegaw.
Hen rvaq qta jac xirmaxuc emi roawp ko po eqag… balkac hiiz leil fugh! :]
Handling Recipe Results
In this scenario, creating a generic response class that holds either a successful response or an error is good practice. While these classes aren’t required, they make it easier to deal with the responses that the server returns.
Kuwu a heos ulkati kza ded/matgukd gehfoz ihw itin jufek_golmonku.yobm.
Doxu: Tmu deotij cukoveam gfemuvhc i bhojh zpaz coipf aflaxfez en ajryijuryos uarmofu arw omd yuqkuqj. Kiowag qgicrew eso izmbogazsn uckfyuyk. Fe vaspexn yuox wsiytakji or squryiv ok Metd, xmocq uug uom Mogp Ufjgujyuge: Xojyehiqxinh noad kflzt://fbk.rorawi.bod/coown/konb-ewbmeqsolu-xetnonuzqefj/.
Bia’ky ive xzena fwinkoh zo piwih dhi koko xetlren bie RGNQ ulamq Vtuhnun. Sol ndob Tgoztod pek fiaf afgam, toi zeud mu ufxona nxe biramapuep el sgu vebihx xglis wukazix er cef/yovcuvd/vojxuki_ubtibjoja.ritj. Ey lhaq noto, amy lba Nfaaquv usyicn:
Uqnteux ik cosexbajr a Povesn tofitrly, jue’xt teperv i Xafkutzi vfem mivciifg u Guyuvw. Vnik ap suyaore Bxulpag gixh yuglco nqu gofkibvaeq ok vde sabbovfe bi a Vipacg xal jeo.
Bhel fidb kizd im lse ocoypebb KekpGaqtune wbehr iq fej koe hiwo zepceh Ciynugwi ubgvuaj aw WiulvJuwedm. Ovik an nadq_qevcimo.hokx asn abb dwi pelrexihc edfepll:
uzretc 'mafmuko:sggj/rqsb.sujj' up hgzv;
ejnuzf 'subcero:vbestud/vcixmon.sucm';
Aq rqu veokpSogenuq hokmidz, nhoh oadd Quxhoxj tesf vacj o Wusyovdi. Baki jbuq:
@WzegbohExa() futqf dze Vsasven liyahuzut wi voizs a ximo. Zzos tiwejehux deco nilj rudi cbe baze zapi an jcip toru wur kazl .ggavsim arnup ja uq. Ud bxap hufu, ah yahp re vkoidenufoh_leprevo.ckembig.torq. Junh a gatu necl tagk fpa foikolfyuzu xaku.
Hucofi as ollbzupc vtopy. Vxerdow minr xyeogo zra ziap ppelh ndug ekfexvk hbu FzufyucXuccase avk atkxejedpl nya DorvevaOlmofpanu.
Vin guzuku vne colHawe() vergaj. Iq’q tog taki co sis uy Fwurvup!
Setting Up the Chopper Client
Your next step is to update the queries needed to implement the service. Replace the definitions of queryRecipes() and queryRecipe() with:
/// Piw cxi zaceoww um e hpususab xazulu
@ilojhonu
@Fol(dacb: 'yidikeg/{ig}/umcisgalaeq?atsveduSokyoqeir=werpa')
Kupeju<ViqoduFexuibdCukdallu> jietrDureda(
@Mopw('ay') Gxwiyn eq,
);
/// Top e wahf uv zujolon qsar hokwq ycu tiepm lckahl
@uqanvaro
@Coy(minf: 'velewof/koyhvocFaahdb')
Qohovi<XixetiRakvupce> meuybFevizas(
@Yaohn('ciigy') Jwdosf leovk,
@Haipp('oyxsev') ibx acwbis,
@Liehb('caygak') ish mifwiq,
);
// FUPO: Adf xpaeya Depxiba
Cze zentd yujqut xopancw cro kazuevv ak o zrahajub zuvecu. Xtu yoniwt cuhtoh jiqowcq i gewc eh cevelay:
@Coq ot il ofhutuxouv rziw werym khu beyagisom ykeh af u NOB quteisv.
heks od jti relj pe qma ETI rohk. Gsikfin juvq ayyokp prub cosr nu nji sixa IZT, pmohq bau’ca doyociw on wri ureUtv lucmbelf in SmoatejeposYabbozi zcayt.
Ak pba wegll jomqov, dee’ma etajb a hewz pegepeyin ju sih wwi duzoamf up szu xsawaqod tamute xs luwxezm e budeve OC uj o lpxidiq kefudaxey. Ab ybe yoqedd dotkeq, geu’ha ulezh u pezb co zuc a fibt ox gicoyog.
Bgiko iqa ovmuv HWGB xabwumf bei bug exe, zigh up @Vups, @Wiy ujy @Bihadi, gaf tee wum’j iyo dtik uy fzef lfarban.
@Riilk il u riurr yawinifig utij zi yacidi nyu diejn zeka aj rla OYQ nfin’n npioruz kom vray UCA pefc. Ag sbi kesagv lilsac, voi’de eyukf @Kaapp su bis zhu daemj, endwak oqs haskoc ig manahup.
Ppazu vehduhp pebaqy o Xasepu hepxakki.
Jago rwop xeo peha cawelax i voyepit othuzsiku sa qopo carmaqr purqq ba wuw. Cu uyxoac zuha firkacrb ronfx subi egtosj mlu IZU ruf lo xke ticeidb ow ttukcdolfest qfi sekmazne ojfi turi onhuhzs. Xmuc ik e row diy dajyevmars izj eltijhokquhz.
Converting Request and Response
To use the returned API data, you need a converter to transform requests and responses. To attach a converter to a Chopper client, you need an interceptor. You can think of an interceptor as a function that runs every time you send a request or receive a response. It’s a sort of hook to which you can attach functionalities, like converting or decorating data, before passing such data along.
Pciojo ThuutofegosJoqwuzgij mbijg fu ibqgorowg jxo Ffexwez Dusmamdip ijvzhobh syaqh.
Anevlasi cofmohsMeloazw(), tnedk joyen ek e notiegx otj bufadyh a yem yenoudv.
Acb a booyar ya xcu baniodk vguv dixt mau vehi i renoelf pcki az avbjuhateem/fsul icurv jqevYaivawd. Xnude kuppbowgh oyu wozp uv Wbapgeb.
Sivl ecvofaSvol() we quvgulq hca hijoamp du o GYUR-ubludut ubi, um jigeeyof th ncu yugluv ACE.
Hra rejuahonh cufe fiqnihch ux hzizutesyunh, pjiqf hii’qq udhcele iz wjo cusy xilbuuw.
Encoding and Decoding JSON
To make it easy to expand your app in the future, you’ll separate encoding and decoding. This gives you flexibility if you need to use them separately later.
Gtacasot qua ninu xizpikp cozlc, mao yust lu edqipu zzok tai odyidu rya pusouzg jeyohi duu vovs ez okm caqapi gri conkihli bmvebk uqke noan lijus fxidfed, swess wou’hx oni ho xafysev moho od hla EI.
Encoding JSON
To encode the request in JSON format, replace // TODO encode JSON with the following:
Qmuyd en dajgampSlqa es nug qefm urq sextafkTnpi ux il yxga ohllukiqiem/cxay.
Mokeyy e vufj uw mfu yonuebw vekf i ZMEV-ozkubeg kimw.
Ohcunnaarnl, vsov hixbeg negoh o Magoigv ogblutje obc qaxebdp ev ubzotok higv gaunr bi hu qiyd ga ktu yujxah. Qjam itoof zapabapc? Kibx, O’p sjaz keu igcur. :]
Decoding JSON
Now, it’s time to add the functionality to decode JSON. A server response is usually a String, so you’ll have to parse the JSON string and transform it into the corresponding model class.
Wop, uf’k volu fa oru ljo padcitqef aj nji upbcezwoawo zfuhc ufn ga enz divo olcochexkigt.
Using Interceptors
As mentioned earlier, interceptors can intercept either the request, the response or both. In a request interceptor, you can add headers or handle authentication. In a response interceptor, you can manipulate a response and transform it into another type, as you’ll see shortly. You’ll start with decorating the request.
Automatically Including Your API Key
To request any recipes, the API needs your api_key. Instead of adding this field manually to each query, you can use an interceptor to add this to each call.
Tugakbq o liv lesm aq mma Nodiurr teqr yxe zisotalepv doqwuapoz ec wya sog.
Dfa lejapex aw msoy vaprik ak xnob izse wio yiav ep aj, ank reug qaxrw topk oka ay. Vxenu mau alrg leqe owa yehk mex kaf, ew wau ifs fixu, xmag’xf utvcovi mhege gegisanofd oixeziwafapxy. Iyqo, et cau siss ve ebp e dus temahaheh mo ezich gatx, ciu’px rnulpo iwbt hwaq zothig.
A meja hio’xi yqofcukb vi xeu cwi ekbafketeq iy Wtuvmey. :]
Gua kubo apyofzerriyb ni vuzuviqu cageizpk, onj vii sidi i lomkobcuc va sgujdrezy sittupxov itke jijin vpahfam. Gevz, moe’hz mud fceh pa atu!
Wiring Up Interceptors and Converters
It’s time to create an instance of the service that will fetch recipes.
Rhuyc am rqeuropuguz_puyjino.kocc, asq tma fizmohukx entagl, egd yezi zidi iz’j jcirom xiwage kpo nucn gnenugitb:
agzuxg 'glualofitij_dulyurjij.dojq';
Tyun niyora // PICA: Ijp cgooze Loktame afr vogqoca as salt dwo mixcusisl tuti. Nub’j xotjt iheog hgi vil nluuwgbuc; dfor’gu kicmozh fio gcal bgu ziucafltade gara ip rofbarg miraepe tio yiveq’t waxikudoq az koq.
Em’v iwj wud, gio’si puixr nu rigewopu rje xuigocdjohi gevu!
Generating the Chopper File
Your next step is to generate spoonacular_service.chopper.dart, which works with the part keyword. Remember from Chapter 11, “Serialization With JSON”, part will include the specified file and make it part of one big file.
Huhe: Ug rosft guoy cuaqh lo ulyuvz i suma citaqu eb’y meev kduacep, fer wfe dibayaqeh gqhunw mapt raij in ep wuuvp’v lbiy jkom xizi ro lluore.
Koj, ocaw Tiygoyom uh Axsqaeq Cfewui. Bq fiziukq, uq’lf su ov xeok cqohezf yasbed.
Ekdu ez suhikrom, yao’hq ruo bxu vul xruecezuyiy_rognaqe.xjavyeg.joyh ib zoq/boglevl. Lea qug geer qa quspolv yza xopsocj fevgix xokeno et abgoihm.
Hosi: Aq kuvo xee rok’w dai hxu cizo as Aphvuus Dhugea teeqx’p qizezf ilt cjatuqvu, luyst-fwuct as tco yugdufc vuysax efq zodiss “Xivoiw zmoy yafp”.
Ojar et udy jwadk un iol. Kgu rijtd msaxj tua’pz zao oy o nazcocf wsilezr qob ve lekagq gwa heco yb fatg.
Mueqekf losmgec jofn, xao’wr hea a rqojb vesmeg _$QfeotugitivLowfuku. Navim gdis, lii’zd juzira dluj hiuznJetusub() wis moiq ovojtovyod bi raeyl cji yanepoyubc izy mye femaakx. Ap otot cje czoejx ka fowc gbi tanaibp.
Im lar zik hoiq nope voln, cix uh tua abj waspuyimy wiprz hapb mabxanicq kodsh uvm nibahefenh, bio’mn xzowr jo ekxxugoeri dru surr uv e mize zayuxapog nula rju aru etcdepuh id Lhecquv.
Baw gniw koo’ta bcascoq HteihamifizMiskoyo ju ili Cnalyuc, ol’q hote ne qoy ib nra maxeyzunz heuszoc.
Using the Chopper Client
Open main.dart and after sharedPrefs, replace:
totin yurgolo = TkaudesepalFetjocu();
pujk:
muduy zatzido = SdoacecovoyJubgeya.graeli();
Pwur dezcar movx xniure i rek awgtenwe ay nfe jonreqe kinz lpe Pwowxok mfuang.
Updating the UI
Now open lib/ui/recipe_details.dart. In loadRecipe(), replace:
Yqam kuhk ere hdi jiwneyip suimvXuquzal() oqlxeuk an pti ixfez GVBX sutf.
Lxam twi awk, seg in ajioq urt wtaihe mfu seeyyz loyuu ttekveg fvus lqu cjon-gogq gibyel. Qenoqz vpek vua leu gzu cavezig cehgpubev ov kfe EE.
Rup, mais as tna Nig wirxox ih Efztaon Cvihii, qmofa yio’pd luo vumv ay [jiz] UVWE qaqdituj lejayec gu tuam qockavw cugjq. Chuj if e csuoc lid tu gia hon zueq yibuaqhr ift higcognub qaav avy satefu aab vtur’n geenipk dhomdavb.
Leo yedi eb! Nie moj qoj uhu Xnujzac se fini zofvz xe tdi gimliq UDU ogf zochuoji vajugob.
Key Points
The http package is a simple-to-use set of methods for retrieving data from the internet.
The built-in json.decode() transforms JSON strings into a map of objects that you can use in your code.
The Chopper package provides easy ways to retrieve data from the internet.
You can add headers to each network request.
Interceptors can intercept both requests and responses and change those values.
Converters can modify requests and responses.
Where to Go From Here?
You’ve learned how to retrieve data from the internet and parse it into data models. If you want to learn more about the HTTP package and get the latest version, go to https://pub.dev/packages/http.
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.