August 9, 2014

Posting Form Data With $http in AngularJS




Cũng khá là lâu rồi không post bài nào về kỹ thuật (toàn mấy bài linh tinh). Hôm nay, nhân tiện mới làm quen với AngularJS, tìm hiểu phần POST data thông qua service $http của AngularJS, mình chia sẻ tí về cách mà mình xử lý.

Khi bạn làm việc với service $http và dùng phương thức POST theo đúng chuẩn thì nó POST luôn nguyên cây JSON đi, khiến cho bạn không thể nhận được dữ liệu bên phía server (mình dùng PHP cho server side)

Cụ thể như sau, nếu bạn dùng thuần túy như sau
$http({
    method: 'POST',
    url: url,
    data: {
        string: "chuoi",
        number: 123,
        arr: [1, 2, 3],
        obj: {
            string2: "chuoi",
            number2: 123,
            arr2: [1, 2, 3],
            obj2: {
                string2: "chuoi",
                number2: 123,
                arr2: [1, 2, 3],
            }
        }
    },
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})

Thì khi post đi, dữ liệu thuộc dạng JSON object, khiến cho phía server không thể lấy data được. Mình đã thêm môt service mới, và thay đổi cách thức trên như sau
$http({
    method: 'POST',
    url: url,
    data: {
        string: "chuoi",
        number: 123,
        arr: [1, 2, 3],
        obj: {
            string2: "chuoi",
            number2: 123,
            arr2: [1, 2, 3],
            obj2: {
                string2: "chuoi",
                number2: 123,
                arr2: [1, 2, 3],
            }
        }
    },
    transformRequest: transformRequestAsFormPost
})

Các bạn chú ấy dòng cuối cùng, đó là một service mới transformRequestAsFormPost nhằm hỗ trợ việc serialize JSON object thành chuỗi có thể post đi được.

Bên dưới là phần định nghĩa service này của mình
angular.module('app')
    .factory("transformRequestAsFormPost",
        function() {
            function transformRequest(data, getHeaders) {
                var serializeData = function(obj, result, keyName) {
                    if (typeof (keyName) === 'undefined') {
                        keyName = null;
                    }
                    var cloneObj = JSON.parse(JSON.stringify(obj));
                    $.each(cloneObj, function(idx, v) {
                        if (v instanceof Object) {
                            var newIdx = encodeURIComponent(idx);
                            var newKeyName = keyName === null ? newIdx : keyName + "[" + newIdx + "]";
                            serializeData(v, result, newKeyName);
                        }
                        else {
                            var key = encodeURIComponent(idx);
                            if (keyName !== null) {
                                key = keyName + "[" + key + "]";
                            }
                            result.push(
                                key + "=" + encodeURIComponent(v)
                                );
                        }
                    });
                };
                var result = [];
                var headers = getHeaders();
                headers[ "Content-type" ] = "application/x-www-form-urlencoded; charset=utf-8";
                serializeData(data, result);
                return result.join("&");
            }
            return(transformRequest);

        });

Đây là cách mà mình đang làm, có thể còn nhiều điều "lạc hậu", nếu bạn có giải pháp tốt hơn, vui lòng chia sẻ giúp mình để mình làm tốt hơn.

No comments:

Post a Comment