Dev to webs {Coding…}

เรียนรู้การพัฒนาซอฟเวอร์ เพื่อความรู้ที่ยั่งยืน

บทที่ 36: การดึงข้อมูลจาก API


1. ความเข้าใจเกี่ยวกับการดึงข้อมูลจาก API

ใน Alpine.js คุณสามารถดึงข้อมูลจาก API ภายนอกได้โดยใช้ Fetch API ภายใน Component

  • เหมาะสำหรับการโหลดข้อมูลแบบ Dynamic เช่น ข้อมูลผู้ใช้, รายการสินค้า, หรือ โพสต์บทความ
  • การดึงข้อมูลสามารถทำได้ใน x-init เพื่อให้ข้อมูลโหลดทันทีเมื่อ Component ถูกสร้าง

2. การดึงข้อมูลด้วย Fetch API

ตัวอย่าง 1: ดึงข้อมูลเบื้องต้น
<div x-data="{ posts: [], fetchPosts() { 
        fetch('https://jsonplaceholder.typicode.com/posts')
            .then(response => response.json())
            .then(data => { this.posts = data; });
    } 
}" x-init="fetchPosts()">
    <h2>Posts</h2>
    <ul>
        <template x-for="post in posts" :key="post.id">
            <li>
                <h3 x-text="post.title"></h3>
                <p x-text="post.body"></p>
            </li>
        </template>
    </ul>
</div>

คำอธิบาย:

  • ฟังก์ชัน fetchPosts() ใช้ Fetch API ดึงข้อมูลโพสต์จาก API
  • x-init="fetchPosts()" เรียกฟังก์ชันเมื่อ Component โหลด

3. การจัดการข้อผิดพลาดในการดึงข้อมูล

ตัวอย่าง 2: เพิ่มการตรวจสอบข้อผิดพลาด
<div x-data="{ posts: [], error: '', fetchPosts() { 
        fetch('https://jsonplaceholder.typicode.com/posts')
            .then(response => {
                if (!response.ok) throw new Error('Network response was not ok');
                return response.json();
            })
            .then(data => { this.posts = data; })
            .catch(error => { this.error = error.message; });
    } 
}" x-init="fetchPosts()">
    <h2>Posts</h2>
    <template x-if="error">
        <p x-text="`Error: ${error}`" style="color: red;"></p>
    </template>
    <ul>
        <template x-for="post in posts" :key="post.id">
            <li>
                <h3 x-text="post.title"></h3>
                <p x-text="post.body"></p>
            </li>
        </template>
    </ul>
</div>

คำอธิบาย:

  • เพิ่มการจัดการข้อผิดพลาดด้วย .catch() และเก็บข้อความใน State error
  • ใช้ x-if="error" เพื่อแสดงข้อความข้อผิดพลาด

4. การแสดงสถานะ Loading ระหว่างดึงข้อมูล

ตัวอย่าง 3: เพิ่มสถานะ Loading
<div x-data="{ posts: [], loading: true, fetchPosts() { 
        this.loading = true;
        fetch('https://jsonplaceholder.typicode.com/posts')
            .then(response => response.json())
            .then(data => { this.posts = data; })
            .finally(() => { this.loading = false; });
    } 
}" x-init="fetchPosts()">
    <template x-if="loading">
        <p>Loading...</p>
    </template>
    <ul>
        <template x-for="post in posts" :key="post.id">
            <li>
                <h3 x-text="post.title"></h3>
                <p x-text="post.body"></p>
            </li>
        </template>
    </ul>
</div>

คำอธิบาย:

  • ใช้ State loading เพื่อแสดงข้อความ “Loading…” ระหว่างดึงข้อมูล
  • ใช้ .finally() เพื่อเปลี่ยน loading เป็น false เมื่อดึงข้อมูลเสร็จ

5. การส่งพารามิเตอร์ใน Fetch API

ตัวอย่าง 4: ดึงข้อมูลพร้อมพารามิเตอร์
<div x-data="{ posts: [], userId: 1, fetchPosts() { 
        fetch(`https://jsonplaceholder.typicode.com/posts?userId=${this.userId}`)
            .then(response => response.json())
            .then(data => { this.posts = data; });
    } 
}" x-init="fetchPosts()">
    <label>
        User ID:
        <input type="number" x-model="userId" @change="fetchPosts()">
    </label>
    <ul>
        <template x-for="post in posts" :key="post.id">
            <li>
                <h3 x-text="post.title"></h3>
                <p x-text="post.body"></p>
            </li>
        </template>
    </ul>
</div>

คำอธิบาย:

  • ใช้ State userId สร้างพารามิเตอร์ userId สำหรับการดึงข้อมูล
  • เรียก fetchPosts() เมื่อค่า userId เปลี่ยน

6. การแสดงข้อมูลแบบ Pagination

ตัวอย่าง 5: การดึงข้อมูลแบบแบ่งหน้า
<div x-data="{ posts: [], page: 1, fetchPosts() { 
        fetch(`https://jsonplaceholder.typicode.com/posts?_page=${this.page}&_limit=5`)
            .then(response => response.json())
            .then(data => { this.posts = data; });
    } 
}" x-init="fetchPosts()">
    <button @click="page > 1 ? page-- : page; fetchPosts()">Previous</button>
    <button @click="page++; fetchPosts()">Next</button>
    <ul>
        <template x-for="post in posts" :key="post.id">
            <li>
                <h3 x-text="post.title"></h3>
                <p x-text="post.body"></p>
            </li>
        </template>
    </ul>
</div>

คำอธิบาย:

  • ใช้ State page สำหรับกำหนดหน้าปัจจุบัน
  • ดึงข้อมูลโพสต์ 5 รายการต่อหน้าโดยใช้พารามิเตอร์ _page และ _limit

7. การใช้ Fetch API แบบ Asynchronous

ตัวอย่าง 6: ใช้ Async/Await
<div x-data="{ posts: [], async fetchPosts() { 
        try {
            const response = await fetch('https://jsonplaceholder.typicode.com/posts');
            this.posts = await response.json();
        } catch (error) {
            console.error('Error fetching posts:', error);
        }
    } 
}" x-init="fetchPosts()">
    <h2>Posts</h2>
    <ul>
        <template x-for="post in posts" :key="post.id">
            <li>
                <h3 x-text="post.title"></h3>
                <p x-text="post.body"></p>
            </li>
        </template>
    </ul>
</div>

คำอธิบาย:

  • ใช้ async/await เพื่อทำให้โค้ดอ่านง่ายและจัดการข้อผิดพลาดได้สะดวก

8. ข้อควรระวังในการดึงข้อมูลจาก API

  1. การจัดการข้อผิดพลาด:
    • ตรวจสอบสถานะของ Response (response.ok) เพื่อป้องกันข้อผิดพลาด
  2. การป้องกันการดึงข้อมูลซ้ำ:
    • ควรจัดการ Loading State เพื่อลดการดึงข้อมูลซ้ำซ้อน
  3. การป้องกันข้อมูลที่ไม่ปลอดภัย:
    • ตรวจสอบข้อมูลที่ได้รับจาก API ก่อนนำไปใช้งาน

สรุป

ในบทนี้ คุณได้เรียนรู้การดึงข้อมูลจาก API โดยใช้ Fetch API ใน Alpine.js ตัวอย่างครอบคลุมการดึงข้อมูลเบื้องต้น, การจัดการข้อผิดพลาด, การเพิ่มสถานะ Loading, และการใช้พารามิเตอร์ในคำขอ การดึงข้อมูล API อย่างเหมาะสมช่วยให้ Component มีความ Dynamic และตอบสนองต่อผู้ใช้งานได้ดีขึ้น!