สร้าง API Provider สำหรับการเรียกใช้งาน API ใน Flutter

wave
มานพ กองอุ่น 8 ก.ค. 2019 17:44:01 14,822

สำหรับบทเรียนรู้นี้เป็นการสร้าง API Provider สำหรับการเรียก API เพื่อนำข้อมูลมาแสดงที่ List View สำหรับตัวอย่างการใช้งาน แต่ก่อนอื่นให้ทำการติดตั้ง package เพิ่มเติมก่อนคือ 

  http: any
  intl: any
  html2md: any
  flutter_markdown: any

โดยเปิดไฟล์ pubspec.yaml จากนั้นเพิ่ม package ลักษณะดังนี้


dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  splashscreen: any
  http: any
  intl: any
  html2md: any
  flutter_markdown: any

สร้าง Class API Provider

lib/api_provider.dart

import 'package:http/http.dart' as http;

class ApiProvider {
  ApiProvider();

  String apiUrl = 'https://api.yourdomain.com/v1';

  Future<http.Response> getPost() async {
    return await http.get('$apiUrl/post');
  }

  Future<http.Response> getPostView(int id) async {
    return await http.get('$apiUrl/post/$id');
  }
}

มี 2 method ที่สร้างเพื่อเรียก API นั่นคือ getPost() โดยจะเรียกรายการ Post ทั้งหมด และ getPostView() โดยเรียกรายการ  Post ที่กดเปิดดู

สร้างไฟล์ helper.dart 

สร้างไฟล์ helper.dart เพื่อเรียกใช้งานในตัวอย่างนี้จะเรียกใช้งานการแปลง timestamp เป็น ตัวหนังสือ เช่น 2 วันที่แล้ว เป็นต้น ดูตัวอย่างโค้ด

import 'package:intl/intl.dart';

class Helper {
  Helper();
  

  String readTimestamp(int timestamp) {
    var now = new DateTime.now();
    var format = new DateFormat('HH:mm a');
    var date = new DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
    var diff = now.difference(date);
    var time = '';

    if (diff.inSeconds <= 0 ||
        diff.inSeconds > 0 && diff.inMinutes == 0 ||
        diff.inMinutes > 0 && diff.inHours == 0 ||
        diff.inHours > 0 && diff.inDays == 0) {
      time = format.format(date);
    } else if (diff.inDays > 0 && diff.inDays < 7) {
      if (diff.inDays == 1) {
        time = diff.inDays.toString() + ' วันที่แล้ว';
      } else {
        time = diff.inDays.toString() + ' วันที่แล้ว';
      }
    } else {
      if (diff.inDays == 7) {
        time = (diff.inDays / 7).floor().toString() + ' สัปดาห์ที่แล้ว';
      } else {
        time = (diff.inDays / 7).floor().toString() + ' สัปดาห์ที่แล้ว';
      }
    }

    return time;
  }
}

สร้างไฟล์ main_page.dart

เป็นไฟล์หลักที่โหลดรายการ post มาแสดงผลใน list tile

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:yourpackage/api_provider.dart';
import 'post_view_page.dart';
import 'package:yourpackage/helper.dart';

class MainPage extends StatefulWidget {
  @override
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  List items = [];
  bool isLoading = true;

  ApiProvider apiProvider = ApiProvider();
  Helper helper = Helper();

  Future fetchPost() async {
    try {
      var response = await apiProvider.getPost();

      if (response.statusCode == 200) {
        var jsonResponse = json.decode(response.body);

        setState(() {
          isLoading = false;
          items = jsonResponse['data'];
          //print(items);
        });
      }
    } catch (error) {
      setState(() {
        isLoading = false;
      });
      print(error);
    }
  }

  @override
  void initState() {
    fetchPost();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Your App Name'),
        ),
        
        body: isLoading
            ? Center(
                child: CircularProgressIndicator(),
              )
            : ListView.builder(
                itemBuilder: (BuildContext context, int index) {
                  var item = items[index];

                  return Padding(
                    padding: const EdgeInsets.only(
                        left: 0.0, right: 0.0, bottom: 4.0),
                    child: Container(
                      color: Colors.white,
                      child: ListTile(
                        onTap: () {
                          Navigator.of(context).push(MaterialPageRoute(
                              builder: (context) => PostViewPage(item['id'])));
                        },
                        title: Text('${item['name']}'),
                        subtitle: Row(
                          children: <Widget>[
                            Icon(
                              Icons.description,
                              size: 14.0,
                            ),
                            Text(' ${item['category_name']} '),
                            Icon(
                              Icons.calendar_today,
                              size: 14.0,
                            ),
                            Text(
                                ' ${helper.readTimestamp(item['created_at'])} '),
                            Icon(
                              Icons.person,
                              size: 14.0,
                            ),
                            Text(' ${item['created_by_fullname']} '),
                          ],
                        ),
                        leading: Image.network(
                          '${item['image']}',
                        ),
                        trailing: Icon(Icons.keyboard_arrow_right),
                      ),
                    ),
                  );
                },
                itemCount: items != null ? items.length : 0,
              ));
  }
}

ทดลอง run 

สร้างไฟล์​ post_view_page.dart

สร้างไฟล์ /lib/post_view_page.dart เพื่อแสดงผลรายละเอียด post 

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:yourpackage/api_provider.dart';
import 'package:yourpackage/helper.dart';
import 'package:html2md/html2md.dart' as html2md;
import 'package:flutter_markdown/flutter_markdown.dart';

class PostViewPage extends StatefulWidget {
  int id;

  PostViewPage(this.id);

  @override
  _PostViewPageState createState() => _PostViewPageState();
}

class _PostViewPageState extends State<PostViewPage> {
  bool isLoading = true;

  Helper helper = Helper();
  ApiProvider apiProvider = ApiProvider();

  String post_category;
  String post_name;
  String post_body;
  int post_created_at;
  String post_created_by_fullname;

  Future fetchPostView() async {
    try {
      var response = await apiProvider.getPostView(widget.id);

      if (response.statusCode == 200) {
        var jsonResponse = json.decode(response.body);

        setState(() {
          isLoading = false;

          post_category = jsonResponse['data']['category_name'];
          post_name = jsonResponse['data']['name'];
          post_body = html2md.convert(jsonResponse['data']['body']);
          post_created_at = jsonResponse['data']['created_at'].toInt();
          post_created_by_fullname =
              jsonResponse['data']['created_by_fullname'].toString();
        });
      }
    } catch (error) {
      setState(() {
        isLoading = false;
      });
      print(error);
    }
  }

  @override
  void initState() {
    super.initState();
    fetchPostView();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('${post_name}'),
        ),
        body: isLoading
            ? Center(
                child: CircularProgressIndicator(),
              )
            : ListView(
                children: <Widget>[
                  Column(
                    children: <Widget>[
                      Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Container(
                            color: Colors.white,
                            child: Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                mainAxisAlignment: MainAxisAlignment.start,
                                children: <Widget>[
                                  Center(
                                      child: Text(
                                    post_name,
                                    style: Theme.of(context).textTheme.title,
                                  )),
                                  Row(
                                    children: <Widget>[
                                      Icon(
                                        Icons.description,
                                        size: 14.0,
                                      ),
                                      Text(' ${post_category} '),
                                      Icon(
                                        Icons.calendar_today,
                                        size: 14.0,
                                      ),
                                      Text(
                                          ' ${helper.readTimestamp(post_created_at)} '),
                                      Icon(
                                        Icons.person,
                                        size: 14.0,
                                      ),
                                      Text(' ${post_created_by_fullname} '),
                                    ],
                                  ),
                                  MarkdownBody(
                                    data: post_body,
                                  ),
                                ],
                              ),
                            )),
                      ),
                    ],
                  ),
                ],
              ));
  }
}

ทดลองกดจากรายการ


ความคิดเห็น

หากบทเรียนรู้มีความผิดพลาดประการใด หรือมีข้อเสนอแนะกรุณาแจ้ง contact@programmerthailand.com

เขียนบทเรียนรู้ของคุณ

รายละเอียด
  • ดู 14,822
  • รักเลย 0
  • หมวดหมู่ Flutter
  • เขียนเมื่อ
  • แก้ไขเมื่อ
  • Tags flutter api
ข้อมูลผู้เขียน
มานพ กองอุ่น

มานพ กองอุ่น

เป็นสมาชิกเมื่อ: 18 ธ.ค. 2009