CRUD App ง่ายๆ ด้วย Angular $resource - Part 1

App หน้าเดียว (SPA: Single-Page App) ที่ทำงานกับ Database ต้องมี CRUD operation (Create Read Update Delete) แต่การจะเขียน SPA ให้ต่อกับ Database โดยตรงนั้น ก็ออกจะเป็นการก้าวก่ายหน้าที่ของบริการ (service) ที่คุมฐานข้อมูลกันเกินไป ดังนั้น เราควรมี layer หนึ่งเพื่อเอาไว้สื่อสารระหว่าง SPA กับ Database

การสื่อสารกันระหว่าง FrontEnd (SPA ของเรา) กับ Backend (Database) จะเป็นในรูปแบบ REST API สิ่งที่ส่งไปมาคือ JSON ซึ่งง่ายต่อการผนวกเข้ากับ AngularJS

$http

โดยทั่วไป เราจะใช้ $http service ของ AngularJS เอาไว้เรียก REST API เช่น
$http.get('/someUrl', config).then(successCallback, errorCallback);
คำสั่งนี้ AngularJS จะสร้าง AJAX GET ไปยัง /someUrl ซึ่ง จะเป็น Asynchronous mode ตลอด (ซึ่งนี่จะนำมาสู่ว่าทำไมถึงได้มี $resource) การเป็น Asynchronous จะทำให้ code ไม่หยุดรอที่บรรทัดนั้น แต่จะทำงานต่อไปเลย ดังนั้น หลังจากบรรทัด $http.get ไม่ได้หมายว่า เราได้ข้อมูลกลับมาแล้ว แต่ Browser อาจจะกำลังติดต่อ server รอข้อมูล อยู่ ด้วยเหตุนี้ จึงต้องมี callback function เพื่อว่า เมื่อ ข้อมูลมาแล้ว จะทำอย่างไรต่อไป เช่น

var customers = [];
$http.get('http://myhose.com/api/customers').then(
  function(resp) { // on success
    customers = resp;
  },
  function(resp) { // on error
    console.error('Fail');
  }
);
console.log(customers.length); // ได้ 0

ที่ console.log(customers.length) บรรทัดสุดท้าย แสดงค่า 0 แทนที่จะเป็นข้อมูลที่ได้มาจาก REST เพราะ ข้อมูลยังมาไม่ถึง $http.get ยังทำงานไม่เสร็จ code ก็ข้ามมาก่อน เพราะความเป็น Asynchronous แต่เมื่อข้อมูลมาแล้ว function // on success จะถูกเรียก แล้วนำเอาข้อมูลนั้นใส่เข้าให้กับ customers

สิ่งที่ได้คือ สัญญา $promise

การเขียนโปรแกรมแบบ Asynchronous นี้ ทำให้เกิดการเขียน code แบบเรียก Callback function เมื่อ $http ที่ทำงานแบบ หน่วงเวลา (defer) ทำงานเสร็จแล้ว (resolved)

การเขียนแบบนี้ ผิดความหมายนะครับ


var customers = $http.get('http://myhose.com/api/customers').then(
  function(resp) { // on success
    
  },
  function(resp) { // on error
    
  }
);
หากเราลองจับสิ่งที่ return ออกมาของ $http.get จบพบว่า ไม่ใช่ตัวข้อมูลเลย แต่กลับเป็น Promise object ซึ่งคือ คำมั่นสัญญาว่า เมื่อทำงานเสร็จ (resolve = true) จะเรียก successCallback ให้

ไว้ผมจะอธิบายเรื่อง promise ในเรื่อง $q service ต่อไป


$resource ช่วยให้ชีวิตดีขึ้น

$resource เป็น hi-level service ที่ใช้งาน $http แทนเรา โดยเมื่อ $http ทำงานเสร็จแล้ว $resource จะจับข้อมูล ยัดใส่ตัวแปรที่เราเอามารอรับค่าให้ โดยที่ ในขณะที่ข้อมูลยังไม่มา (resolve = false) นั้น ตัวแปรนั้นจะเป็น $promise เช่นเดียวกับ $http แต่เราไม่ต้องมาเขียน successCallback แล้ว
var customers = $resource('/someUrl');
ง่ายเวอร์ครับ

การใช้งาน $resource มีอะไรอีกมาก ไว้จะมาเล่าให้ฟังในบทความต่อๆไป

Comments