Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 10.08.2013, 15:37
Интересующийся
Отправить личное сообщение для tktl Посмотреть профиль Найти все сообщения от tktl
 
Регистрация: 07.09.2011
Сообщений: 22

Организация обработки ответов RESTfull сервера
Добрый день.
Есть REST сервер, который всегда отвечает JSON вида:

{
    code: 2, // код результата выполнения запроса. например 1 - ОК, 4 - запрошеный ресурс не существует, 9 - ошибка валидации и тп
    data: [] // массив передаваемых данных
}


HTTP код ответа сервера всегда 200.

В Angular app есть сервисы:

angular.module('teslaApp.services', ['ngResource']).

    value('uapi_dir', 'путь к API').

    factory('Items', ['$resource', 'uapi_dir', function ($resource, uapi_dir) {
        return $resource(uapi_dir + '/item/:id', {id: '@id'}, {
            query: {method: 'GET', isArray: false},
            update: {method: 'PUT'}
        });
    }]).


    factory('Currency', ['$resource', 'uapi_dir', function ($resource, uapi_dir) {
        return $resource(uapi_dir + '/currency/', {}, {});
    }])

    // еще порядка сорока сервисов по работе с ресурсами

;


В контроллерах работа с ресурсами идет приблизительно так:

Items.query(function (resp) {
            // обработка удачного ответа
        }, function (respErr) {
            // обработка ошибки. если c REST сервером что-то не так.
        });



Этот проект мне достался на "доделать" и пришлось срочно разбираться с Angular.
В написанном до меня коде в обработке удачных ответов REST (не удачные вообще не обрабатываются) стоит временная заглушка:

Items.query(function (resp) {
            if (resp.code === 1) {  // code 1  - ответ REST сервера, когда все ОК (аналог HTTP 200)
                // дальше работа
            }

        }, function (respErr) {
        });


Такая вот заглушка стоит везде. Само собой, надо разбирать остальные коды, выводить ошибки и тп.
Контроллеров много, работы с ресурсами в них, еще больше.

Нужна отдельная функция, которая будет смотреть code и писать ошибки куда-то в scope. Что-то типа такого:

// response  - ответ REST
// msg_scope - $scope, куда надо поместить сообщение в зависимости от кода выполнения запроса
function restResponseHandler (response, msg_scope) {
    var is_ok = true;
    switch (response.code) {
        case 8:
            is_ok = false;
            $scope[msg_scope] = 'Не верный логин или пароль';
            break;
        case 41:
            // не авторизован
            $location.path('/login');
            break;
        // и тд
    }
    return is_ok;
}


Из контроллера ее можно было-бо вызывать вот так:
Items.query(function (resp) {

            if (restRespHandler(resp, 'formErr')) {  // formErr - $scope.formErr -в него выводятся ошибки при работе с формой
                // дальше работа
            }

        }, function (respErr) {
                restRespHandler(resp);
        });


Не самое изящное, но на ум пока лучше не приходит.

Где такой функции место, исходя из философии Angular? Это вроде не сервис (работа со scope) и не фильтр.
Может кто-то сталкивался?
Кто как общается с REST? Подскажите, пожалуйста.
Ответить с цитированием
  #2 (permalink)  
Старый 10.08.2013, 20:20
Профессор
Отправить личное сообщение для Dmitriyff Посмотреть профиль Найти все сообщения от Dmitriyff
 
Регистрация: 22.07.2012
Сообщений: 164

1) ресурсы у ангуляра сыроваты, добавил в них функцию парсера для разбора ответа
2) сервер возращает не только 200 статус, так что ошибки попадают по назначению
3) глобальный метод обработки ошибок
App.config(function( $httpProvider ) {
	$httpProvider.responseInterceptors.push(function($q, $window, $rootScope, $location) {
		return function(promise) {
			return promise.then(function(response) {
				// success
				return response;
			}, function(response) {
			    // error
				return $q.reject(response);
			});
		}
	});


где App ваше приложение
Ответить с цитированием
  #3 (permalink)  
Старый 10.08.2013, 22:10
Интересующийся
Отправить личное сообщение для tktl Посмотреть профиль Найти все сообщения от tktl
 
Регистрация: 07.09.2011
Сообщений: 22

Большое спасибо за ответ. Тем более с кодом.

Насколько я понимаю, в этот метод нельзя передать из контроллера имя свойства $scope, которое связано с представлением. Ответ сервера просто перехватывается этим методом.

Хотелось бы писать так:

<div class = "form_error"> {{ formError }}</div>
Ответить с цитированием
  #4 (permalink)  
Старый 10.08.2013, 22:42
Профессор
Отправить личное сообщение для Dmitriyff Посмотреть профиль Найти все сообщения от Dmitriyff
 
Регистрация: 22.07.2012
Сообщений: 164

если такой вывод ошибки у вас используется глобально, то вам ничего не мешает записывать ответ в $rootScope.formError
так как все $scope наследуются от $rootScope
вывод можно таким и оставить. а если боитесь что где-то может переписываться, то сделайте так {{ $root.formError }}
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Обработка ответов сервера Rock877 Работа 1 12.07.2012 04:04
"success" и "failure" приём данных с сервера ??? potkin ExtJS 8 30.05.2012 09:27
Перехват Ajax ответов от сервера shock-in AJAX и COMET 6 27.01.2011 16:49