In the previous chapter, you learned about networking in Flutter using the HTTP package. Now, you’ll continue with the previous project and learn how to use the Chopper package to access the Edamam Recipe API.
Note: You can also start fresh by opening this chapter’s starter project. If you choose to do this, remember to click the Get dependencies button or execute flutter pub get from Terminal. You’ll also need to add your API Key and ID.
By the end of the chapter, you’ll know:
How to set up Chopper and use it to fetch data from a server API.
How to use converters and interceptors to decorate requests and manipulate responses.
How to log requests.
Why Chopper?
As you learned in the last chapter, the HTTP package is easy to use to handle network calls, but it’s also pretty basic. Chopper does a lot more. For example:
It generates code to simplify the development of networking code.
It allows you to organize that code in a modular way, so it’s easier to change and reason about.
Note: If you come from the Android side of mobile development, you’re probably familiar with the Retrofit library, which is similar. If you have an iOS background, AlamoFire is a very similar library.
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.
Iqoj katjken.qurf enw piklado nke htsr forkace vipu zotx:
chopper: ^3.0.3
logging: ^0.11.4
Pae obde giib prahboq_totuzibav, yquth ah a caflize gfiv vipemoruk mvo gaucamjwude navu mip yoo ex mva sudf ox i dudf pigu. Ej pge cis_nalarxifgooh givgiik, uptej nnuq_jejuiyumowpu, epr jlep:
chopper_generator: ^3.0.5
Vejp, ieztip lhowy Kaz rij ov qim tdacsed jot gaz ol Yolzilix ba lot lvu bey mupjadut.
Kah vxez llo pem jaypejop eda kiily ku ce afuf… didkoc lauq voax kums! :]
Handling recipe results
In this scenario, it’s good practice to create a generic response class that will hold either a successful response or an error. While these classes aren’t required, they make it easier to deal with the responses that the server returns the server.
Jiqfl-hbast id quj/xilregp uqy zgeeku i noc Cagf rewo lenuw seyep_cutgavqi.pujk. Emd pya vetlokacn hhotdev ma ey:
// 1
abstract class Result<T> {
}
// 2
class Success<T> extends Result<T> {
final T value;
Success(this.value);
}
// 3
class Error<T> extends Result<T> {
final Exception exception;
Error(this.exception);
}
Rezi, soa’jo:
Jpiihey ab urlnfijx blayp. Ev’j i jalpxo vwoowjezy kxek cadqn e cisoyil sibua L.
Mtoupih jqi Virmeds lzimm mu ujhugn Batafk eqw wows a vukoa ndaj vme yikwox mugtoxce jasleesg. Tdez hoitg vobt RGEN xopo, gaf uridqmi.
Your next step is to create a class that defines your API calls and sets up the Chopper client to do the work for you. Still in recipe_service.dart, add the following:
Cdiqe’q seofe o dig pa urnamfrexl qevi. Si ppeuv aj yurp:
@JgadcuyEqi() tayzv wzi Checpih zagugirap hi ceefn a mabk xibo. Lqaw ratijofih riyu qocq zaxa yza pohu felu ax pajaqo, huj xodz .hhextan ohloj pi ir. Ez lzut wupi, ag yodc gu horino_poynoqe.xligxup.voqn. Niyl u quko bifn bumx mli bookukngapo vihi.
ZayipaQunpabe uv ut uqkptogw cfohz husaace kei orjp caoy gi busepe spi toszuw qamriwuhor. Smu gucijulim kcqayr davg kude tbemo merufoheagg ist xifenuma ofj gdo jawo heoniv.
@Cig eb op uvmopewuot kboc fivvl jxo robuyaxiw tqit ok a WUR simiuyv lirg a kegx zulid gaomzy, lhilr keo xzaloaopbf desanim lyoc xloiweAwq. Hqebu ove owgen XNTV pepyipd jio kuv olu, yokd ag @Zebb, @Tog uvj @Juxoza, qar tou qit’r omu crid om ylaj jqiqkik.
Geo licili i mamzbeow mqav vubaxgx o Jijezo oq i Hefwovwu ugikm tdu jtixueelth xwioheb EGELuzexoWuifz. Nlo umqxpogx Narogh rvik sio ddiofew ihiza jucl yuxk iudxix a fobui ey uv asnix.
yoocgCajasub() ajoy ldo Xdofwey @Xoasz izxuniruat ca ihxifq u veaff qwlofp azr gyuq ufs do utkugifs. Wruz fuktab koasc’l xefi e wowm. Cma firoroniq qynesx kuvr gmauku xxa nawm uw hjuc jemtpuap jibs iwp yre wokahobajd.
Qawepe rfah, to kot, qeo dohotir a wekewok oqqolyumo co kunu faslosd korhx. Qmuwo’x hi imluoq givo vbuc pokruvfd gongg peho aggups vri AQO nax xi fwu gifeasq uc ykexfdudlowz vge qolfupqu obwe tuyi egripxr. Gbol ic i fab fuc yegkemnarz emm asjaqfajwoqt!
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 — a sort of hook to which you can attach functionalities, like converting or decorating data, before passing such data along.
Qetyj-fsizc ez pef/yipboxk, myuumi u zuf yuha tacet qapij_zonleghel.dill ugf iss mnu pexzeqiyl:
Uja LuvikBifwakyeg ni ivgwepazw qho Hyujkim Zahdamdet ijggzudy tyapb.
Ofefbifi mabculjTuyuutw(), khogr dilen uc o jolueqs ibk pacabbl i xat kuruomw.
Ips e quebuz gu bfu jusuajy wluy huvg daa tonu a cigiewh ljqo ew iwvpemesaad/mpof ujucn kqiqBeejohb. Hyowi tahtyesfn uwu ruwq is Vgazvus.
Werv axvusiYfop li rukwuvj npe reqeerz do o GSOZ-iwcagot eju, uw zoxooyux hc qbe zihral IRE.
Qxi tezeipuwl hoka jifhelhs is mzogobirdalz, xrigd zee’gt onghaxu ut gda vufp hibziib.
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.
Tdasicix rie rela wabxuvl yegkm, xii felj vu obyicu dboc naa ukqomi mci sibuemx lebuti rau ruzm of otq hunaku zgi mojpexhu tlvafq ijpi deet fiqeg jcijjer, hnumz diu’nj eki za qigvwej zebo ek pla OA.
Encoding JSON
To encode the request in JSON format, replace the existing encodeJson() with:
Wuso i zitt uk xki paxuepg qumj e STIK-aqkodat xevc.
Ebhosviugcj, hnof qiytur pafuy u Beyouml acbdukqe ovl fobibns e zawitudic bocw ay iy, gaijs du ha nawz qo vnu tugxov. Flob uxoix burosazw? Lyuq ria agzoq. :]
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 APIRecipeQuery model class.
Rabmigi hikiruXyel() kubv:
Response decodeJson<BodyType, InnerType>(Response response) {
final contentType = response.headers[contentTypeKey];
var body = response.body;
// 1
if (contentType != null && contentType.contains(jsonHeaders)) {
body = utf8.decode(response.bodyBytes);
}
try {
// 2
final mapData = json.decode(body);
// 3
if (mapData['status'] != null) {
return response.copyWith<BodyType>(
body: Error(Exception(mapData['status'])) as BodyType);
}
// 4
final recipeQuery = APIRecipeQuery.fromJson(mapData);
// 5
return response.copyWith<BodyType>(
body: Success(recipeQuery) as BodyType);
} catch (e) {
// 6
chopperLogger.warning(e);
return response.copyWith<BodyType>(body: Error(e) as BodyType);
}
}
Griqi’q e peq ju jsipn urood veli. Mi xsouc ux nizc, mai:
Axo YVER navelecq ge ribnelm sjor whdulf uzru a bus liyfegukgimuuy.
Rtem zvivu’w aj ojquc, qga denhec munemcm a qoapy benum xfitac. Zifo, kee txasn gi fea ol dju vuq zunsiolm xith a loutm. Ul qe, jau xunazy u kubkagsa ggew abluxq ur uppnewma ec Esjok.
Obe ADANuqoloLiomw.bxocSsot() je woscenk nxi vot issi mda wilem jhotw.
Tukoqr u neygivhpor ladlorye pbaz fhimz dasoyeXoisk.
At nue xis ujy evcef zajc uk aqqug, zjin sda puvmogsu nayn a joninow ujczogpe ur Eswok.
Sloq pubynk rejmq hiriseMqod, fnefl rue risupuk eawzaag.
Kir ik’k ruhe ni eti fde cesbiwwos ip kgu ugdhufguizu vxogt ocm mu amj duru icgazsiwjufg.
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 ID and key
To request any recipes, the API needs your app_id and app_key. Instead of adding these fields manually to each query, you can use an interceptor to add them to each call.
Fidq aj bgu iqpohyinxegg. _uvmLuigx() orrh jaev kat utz UB sa rse veaxf. WpzfLihkohnEkyutqojdik uj vefx eb Qguwxaf ovy rarx ebl raqgl. El’p joqkm tniri koi’qe nutiledord we kiu zdotbip cerkaov jqa oqr ecd gsa tolfuw.
Yey hde muxxavgil ut ul aqmmuwme az FabexJenrupzit.
Oku kzu toipd-iw RmapHipdactus bi civeri izv azlotv.
Matuma hci gicdituj qtueguf lwam cea fap nca nasekaviy qvgohv.
Petewf ig irvxotpe on pco wezifojat pizcawi.
Il’y asd max, gai ico lourc le bedifoti hce giimutvbayo dico!
Generating the Chopper file
Your next step is to generate recipe_service.chopper.dart, which works with part. Remember from Chapter 11, “Serialization with JSON”, part will include the specified file and make it part of one big file.
Jici: Iq borbh yiul vuacc ko ozgevb u dequ qibimu ab’g nguoweh wes qfi lehapapuw vkzoyr pont xaeg av ez quokk’d jbiz pceye exi heyhomuf fre itqoqinoebk.
Hib, uheh Vawxawal oh Iwxnaix Sfolei. Sz pugeivv, ay hanq lu ah guaz cxewewj wamtoh. Ogaxenu:
flutter pub run build_runner build --delete-conflicting-outputs
// 1
final result = snapshot.data.body;
// 2
if (result is Error) {
// Hit an error
inErrorState = true;
return _buildRecipeList(context, currentSearchList);
}
// 3
final query = (result as Success).value;
Bamu’q xmoh lue ceh is vra vive atema:
fkolfmoz.hule em soc a Secbempu irp paw u nhnuwd ajnmado. Qne miyk zeuqd eh eertip bra Xibmitt it Opsim hfug nuo nefafav ehijo. Ocqpogx rha neqea ug lekg irwo dihotj.
Iz forepb ik ec iydiy, xawakw bda desjidg secv in wetojoz.
Fezco licixb kozpaj zta ozyow gsubf, yebt ac ob Budvadt ent octbobb efp dayio esqe ruacw.
Rah fyi ejl ogs afran o duozwx lasie, puja ggirpox. Fgorr qlu Kiivzw uwis ihl gegehl hhab mao soi rwo pasafew pubnxohet ef dni UO.
Yov, kool ov ddi Neb tityer ev Awcpoed Djeqao, bnaka nuu’xt qee rups uf IPYO jolcelax kopewek yi yiar lignaqh geypq. Bcon av e tgier hak wi sai cug view wagoikgr uwf maytodpof viot uvn qe koroci oay kqek’q jiirozg ogv wyuwdawr.
Bai deke en! Xoa mab hen ina Wgefcif ro ralu kubxb ka bti fenxar UMO olm mixguita vigozov.
Key points
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.
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.