Flutter: How to encode/decode JSON in Flutter.
Encode = เข้ารหัส ให้เป็น json String (เพื่อส่ง data ไป BE)
Decode = ถอดรหัส ให้เป็น Map (เพื่อนำ data จาก BE มาใช้)
JSON = Data format ที่เราคุ้นเคยในการเรียก API
แล้วมันเชื่อมโยงเกี่ยวข้องกันยังไงใน Flutter เด๋วผมจะอธิบายให้ฟังคับ
จริงๆแล้วในการเขียน Flutter คือการเขียนในส่วนของ FE เพื่อไปเชื่อมกับ BE (จะเป็นยี่ห้ออะไรก็ได้) โดยการติดต่อกันนี้เราจะเชื่อมกันด้วย Restful API และ return เป็น JSON มาให้ Flutter ใช้งานต่อ
ดังนั้นเมื่อตัวกลางคือ json จึงต้องมีกระบวนการแปลง
- แปลง Dart to Json (Encode) = ใช้ในการแปลง Object (Map in Dart)ให้เป็น Json String สำหรับส่งออกไปให้กับ Backend (เช่น ส่งค่าสำหรับ login ไปขอ token)
- แปลง Json to Dart (Decode) = ใช้ในการแปลง json String ที่รับเข้ามา ให้เป็น Object (Map in Dart) เพื่อใช้ใน App ของเราซึ่งโดยปกติเราจะใช้แบบนี้เป็นส่วนใหญ่
jsonDecode()
เรารู้แล้วว่าใช้สำหรับรับค่าเข้ามา ซึ่งแน่นอนว่าต้องใช้กับ GET Method
ในที่นี้ผมจะทดสอบโดยใช้ api จาก reqres.in นะคับ
https://reqres.in/api/users?page=1
และจะได้ data ออกมาหน้าตาแบบนี้
ต่อไปมาดูทาง code ของ dart กันบ้าง เราจะเขียนแบบ Asynchronous (พวก http จะทำงานเป็น async) เพื่อ call API มาแสดงผล ซึ่งมีขั้นตอนอยุ่ 3 อย่างนะคับ
- Install http package.
- Create model or use dynamic instead
(ในที่นี้ผมจะใช้วิธี dynamic นะคับ คือ เขียนใส่เข้าไปใน UI เลย
แต่ถ้า project ใหญ่ๆอาจแยกไปทำเป็น service ตังหาก และวิธีการสร้าง model ผมเคยเขียนไว้แล้ว ที่นี่
Dynamic : ข้อดีคือเร็วกว่าและจะสะดวกเวลามาแก้ไขกรณีที่ BE มีการเปลี่ยนชื่อตัวแปรเพราะแก้ที่เดียว แต่ข้อเสียคือต้องพิมพ์ให้ถูกต้องและไม่มี autocomplete ช่วยModel : ข้อดีคือจะสะดวกเพราะแค่พิมพ์ dot(.) ก้อมี autocomplete ช่วยเลย และสามารถดัก null ไว้ที่ model ทั้งหมดได้ด้วยทำให้ code ดูคลีนเพราะมีการแยกระหว่าง UI กับ Model ที่แก้ข้อมูล แต่ข้อเสียคือเมื่อ backend มีการแก้ไขตัวแปร จะต้องมาตามแก้ไขใน model ให้ครบทุกจุดด้วย
3. Write code to call API.
- เพิ่มในส่วนของการ get data เข้ามา และใช้ function
convert.jsonDecode()
ในการแปลง json string ให้เป็น Map<String, dynamic> เพื่อนำไปใช้งานต่อ - จากนั้นจึงนำ
_members['data']
ไปเข้า for loop เพื่อดึงออกมาทีละตัวและใส่ค่า value ที่เป็น object เข้าไปในList members
เพื่อให้พร้อมสำหรับนำไปแสดงผลใน UI ต่อ
จากนั้นนำค่า members
ที่มี List ของ objects ทั้งหมดแล้ว มา render ผ่าน ListView.separated()
jsonEncode()
สำหรับ jsonEncode() เราจะต้องส่ง object เข้าไปนะคับ ซึ่งจะใช้กับ POST Method
โดยผมจะทดสอบจาก UI ก่อนหน้านี้เลย โดยเมื่อมีการกดที่ ListTile()
จะส่งค่า username + password เข้าไปและได้รับ token กลับมา
จากนั้นจะนำ response ที่ได้จาก POST Method
มาผ่าน jsonDecode()
อีกครั้งตามรูปด้านบนนะคับ เพื่อเก็บไว้ในตัวแปร showToken ที่เป็น Map เพื่อนำมาแสดงใน Text ด้านล่างแบบนี้
ในงานจริงถ้าหน้านั้นๆมีหลายส่วน เราอาจแยกส่วนที่ display แต่ละส่วนออกมาเป็น class ได้เลย เพื่อให้ง่ายในการจัดการในลักษณะนี้
จบล่ะ เรื่อง jsonDecode() และ jsonEncode() ใน Flutter สำหรับ API
Code ก่อนที่จะแยกส่วนมาสร้างเป็น class เพื่อให้ดูคลีนนะ :
PS:
ก่อนจบ ขอเปรียบเทียบการใช้ dynamic กับ model ในส่วนของ GET Method ว่ามีความต่างกันยังไง
ซึ่งในการสร้าง model เพียงแค่ copy json reponse ไป auto generate ได้เลยใน https://app.quicktype.io/ และสามารถ
Make all properties optional
เพื่อป้องกัน runtime error เมื่อได้รับค่า null
สรุป:
Encode = แปลง object ให้เป็น String เพื่อส่งไป BE
Decode = แปลง String ให้เป็น Object เพื่อนำมาใช้
การใช้ Model จะช่วยลดความผิดพลาด และ code เป็นระเบียบดูง่ายและคลีน
แล้วพบกันใหม่ครับ
GRASSROOT ENGINEER.