MyDiaryคอร์ส Flutter · 6 สัปดาห์ ทุกสัปดาห์
สัปดาห์ที่ 3 · ใบงาน · Lab
สารบัญหน้านี้

ใบงานฝึกปฏิบัติ สัปดาห์ที่ 3: MyDiary — เชื่อมต่ออินเทอร์เน็ต

ก่อนทำ Lab: ต้องผ่านส่วนที่ 3 ในเอกสารสอน (แอปแสดงคำคมจากเน็ต + FutureBuilder + รีเฟรช ครบ 6 ขั้น) Lab นี้ = ต่อยอดของเดิม ให้ใช้ API ได้คล่องและจัดการกรณีต่างๆ

การส่ง: โปรเจกต์ + คลิปสั้น (แสดงคำคมโหลด → กดรีเฟรช → ปิดเน็ตแล้วไม่ crash)


Lab 1 — ปรับปรุงการแสดงตอนโหลด/ผิดพลาด

เป้าหมาย: ทำให้ 3 สถานะของ FutureBuilder ดูดีขึ้นและมีปุ่มลองใหม่

ขั้นที่ 1 — ตอน error เพิ่มปุ่ม "ลองใหม่" (แก้ส่วน hasError):

} else if (snapshot.hasError) {
  return Padding(
    padding: const EdgeInsets.all(16),
    child: Column(
      children: [
        const Text('โหลดคำคมไม่ได้', style: TextStyle(color: Colors.grey)),
        TextButton(
          onPressed: () {
            setState(() {
              _quoteFuture = ApiService.fetchQuote();   // โหลดใหม่
            });
          },
          child: const Text('ลองใหม่'),
        ),
      ],
    ),
  );
}

ขั้นที่ 2 — ตอนโหลด เพิ่มข้อความใต้วงกลม:

if (snapshot.connectionState == ConnectionState.waiting) {
  return const Padding(
    padding: EdgeInsets.all(16),
    child: Column(
      children: [
        CircularProgressIndicator(),
        SizedBox(height: 8),
        Text('กำลังโหลดคำคม...', style: TextStyle(color: Colors.grey)),
      ],
    ),
  );
}

ผลที่ควรได้: ตอนโหลดเห็นข้อความ / ตอน error มีปุ่มลองใหม่กดได้


Lab 2 — เพิ่ม try-catch ใน ApiService

เป้าหมาย: จัดการ error ให้ละเอียดขึ้น แยกกรณีเน็ตหลุดกับเซิร์ฟเวอร์พัง

แก้ fetchQuote ใน api_service.dart:

static Future<Quote> fetchQuote() async {
  try {
    final url = Uri.parse('https://dummyjson.com/quotes/random');
    final response = await http.get(url).timeout(const Duration(seconds: 10));

    if (response.statusCode == 200) {
      final data = jsonDecode(response.body);
      return Quote.fromJson(data);
    } else {
      throw Exception('เซิร์ฟเวอร์ตอบผิดพลาด (${response.statusCode})');
    }
  } catch (e) {
    // จับ error ทุกแบบ (เน็ตหลุด/timeout/เซิร์ฟเวอร์พัง)
    throw Exception('เชื่อมต่อไม่ได้ ตรวจสอบอินเทอร์เน็ต');
  }
}

อธิบาย: - .timeout(Duration(seconds: 10)) = ถ้ารอเกิน 10 วินาที = ยกเลิก (กันค้างตลอดกาล) - try { } catch (e) { } = ถ้ามี error ที่ไหนในบล็อก try → กระโดดมาทำ catch
- แปลง error ทางเทคนิคเป็นข้อความที่ผู้ใช้เข้าใจ

ทดสอบ: ปิดเน็ต → รันใหม่ → ควรเห็นข้อความ error ที่สุภาพ (ไม่ใช่ error ดิบยาวๆ)

ผลที่ควรได้: ปิดเน็ตแล้วข้อความ error อ่านเข้าใจง่าย มี timeout กันค้าง


Lab 3 — บันทึกคำคมที่ชอบลง SQLite

เชื่อม API เข้ากับ SQLite (รวมความรู้ 2 สัปดาห์)

เป้าหมาย: กดปุ่มบันทึกคำคมที่ชอบ → เก็บเป็นบันทึกใน DB โดยเพิ่ม column quote (ผสาน API + SQLite)

แนวคิด: คำคมจากเน็ต (quote) + ปุ่มบันทึก → กลายเป็นบันทึกในไดอารี (ใช้ SQLite สัปดาห์ 2)

นี่คือจุดสำคัญ: แอปตอนนี้รวมทุกอย่าง — ดึงจากเน็ต (สัปดาห์ 3) + เก็บถาวร (สัปดาห์ 2) + แสดงรายการ (สัปดาห์ 1)


เช็คลิสต์ก่อนส่ง

☐ Lab 1 — โหลด/error ดูดีขึ้น มีปุ่มลองใหม่
☐ Lab 2 — try-catch + timeout ใน ApiService
☐ Lab 3 — บันทึกคำคมลง SQLite ได้ (ผสาน API+DB)
☐ คลิป: คำคมโหลด → รีเฟรช → ปิดเน็ตไม่ crash