Flutter: How to encode/decode JSON in Flutter.

Grassroot Engineer
3 min readAug 7, 2021

--

Encode = เข้ารหัส ให้เป็น json String (เพื่อส่ง data ไป BE)
Decode = ถอดรหัส ให้เป็น Map (เพื่อนำ data จาก BE มาใช้)
JSON = Data format ที่เราคุ้นเคยในการเรียก API

แล้วมันเชื่อมโยงเกี่ยวข้องกันยังไงใน Flutter เด๋วผมจะอธิบายให้ฟังคับ

จริงๆแล้วในการเขียน Flutter คือการเขียนในส่วนของ FE เพื่อไปเชื่อมกับ BE (จะเป็นยี่ห้ออะไรก็ได้) โดยการติดต่อกันนี้เราจะเชื่อมกันด้วย Restful API และ return เป็น JSON มาให้ Flutter ใช้งานต่อ

https://epb.bibl.th-koeln.de/frontdoor/deliver/index/docId/1498/file/flutter-for-the-dev-of-large-scale-ref-app.pdf

ดังนั้นเมื่อตัวกลางคือ 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 ออกมาหน้าตาแบบนี้

หน้าตาของ response.body

ต่อไปมาดูทาง ​code ของ dart กันบ้าง เราจะเขียนแบบ Asynchronous (พวก http จะทำงานเป็น async) เพื่อ call API มาแสดงผล ซึ่งมีขั้นตอนอยุ่ 3 อย่างนะคับ

  1. Install http package.
  2. 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 ต่อ
get data from API

จากนั้นนำค่า members ที่มี List ของ objects ทั้งหมดแล้ว มา render ผ่าน ListView.separated()

render to show result from ListTile()

jsonEncode()

สำหรับ jsonEncode() เราจะต้องส่ง object เข้าไปนะคับ ซึ่งจะใช้กับ POST Method โดยผมจะทดสอบจาก UI ก่อนหน้านี้เลย โดยเมื่อมีการกดที่ ListTile() จะส่งค่า username + password เข้าไปและได้รับ token กลับมา

Created function for testing jsonEncode()

จากนั้นจะนำ response ที่ได้จาก POST Method มาผ่าน jsonDecode() อีกครั้งตามรูปด้านบนนะคับ เพื่อเก็บไว้ในตัวแปร showToken ที่เป็น Map เพื่อนำมาแสดงใน Text ด้านล่างแบบนี้

เมื่อมีการ tab ที่ ListTile() จะแสดง response ที่ได้จากการ post ออกมา

ในงานจริงถ้าหน้านั้นๆมีหลายส่วน เราอาจแยกส่วนที่ display แต่ละส่วนออกมาเป็น class ได้เลย เพื่อให้ง่ายในการจัดการในลักษณะนี้

Refactor เพื่อให้ดูคลีนขึ้น

จบล่ะ เรื่อง jsonDecode() และ jsonEncode() ใน Flutter สำหรับ API

Code ก่อนที่จะแยกส่วนมาสร้างเป็น class เพื่อให้ดูคลีนนะ :

Example code to test.

PS:

ก่อนจบ ขอเปรียบเทียบการใช้ dynamic กับ model ในส่วนของ GET Method ว่ามีความต่างกันยังไง

ซึ่งในการสร้าง model เพียงแค่ copy json reponse ไป auto generate ได้เลยใน https://app.quicktype.io/ และสามารถ Make all properties optional เพื่อป้องกัน runtime error เมื่อได้รับค่า null

Compare dynamic and model when get response.body from API.
Compare in part of UI.

สรุป:

Encode = แปลง object ให้เป็น String เพื่อส่งไป BE
Decode = แปลง String ให้เป็น Object เพื่อนำมาใช้

การใช้ Model จะช่วยลดความผิดพลาด และ code เป็นระเบียบดูง่ายและคลีน

แล้วพบกันใหม่ครับ
GRASSROOT ENGINEER.

--

--

Grassroot Engineer
Grassroot Engineer

Written by Grassroot Engineer

ATM engineer who is interested in CODING and believe in EFFORT. — https://grassrootengineer.com

No responses yet