Прежде чем что-то писать дальше на ангуляре, советую изучить
styleguide и следовать ему.
Особенно плохи такие вещи:
1) использование .success/.error вместо .then в $http; Они давненько deprecated. Только .then.
2) создание лишних deferred-объектов. метод .then() и так вернёт промис.
3) в методе .getOrders твоего сервиса в одном случае возвращается промис, а в другом просто null. всегда возвращай промис. просто там, где всё плохо нужно делать reject
4) сохранять список в сервисе, а потом искать элемент по id в нём не самая хорошая идея. нужно всегда запрашивать с сервера свежие данные
В общем, твой сервис должен выглядеть примерно так:
ordersFactory.$inject = ['$http', '$q', 'AuthService'];
function ordersFactory($http, $q, AuthService) {
return {
getList: getList,
};
function getList() {
// лучше, чтобы был промис
// Выстраиваем цепочку промисов
return AuthService.isAuthorized()
.then(() => $http.get('/api/orders')) // тут шлём запрос,
.then(response => response.data); // bи просто возвращаем данные ответа
// в итоге, сервис зарезолвит промис и вернёт данные
// только если все в цепочке промисов зарезолвят их
// если где-то будет reject, то его можно будет отловить выше
// либо можно отловить reject тут и что-то сделать, тут уж тебе решать
}
function getById(id) {
AuthService.isAuthorized() // лучше делать запрос на сервер, чем пытаться найти в массиве
.then(() => { $http.get('/api/orders/' + id))
.then(response => response.data);
}
function getByIdInList(id) { // но если сильно хочется искать элемент на клиенте
return getList() // то лучше сделать так
.then(orders => { // обрабатываем данные, полученные из getList
// при условии, что они зарезолвятся
// тут ищем
for (let i = 0; i < orders.length; ++i) {
if (orders[i].id === id) {
return $q.resolve(orders[i]);
}
}
return $q.reject();
});
}
}
Ну и если ты не работаешь с DOM, функция линк не нужна, контроллера директиве хватит.
Ну а ответ на твой вопрос кроется тут:
vm.setOrder = (id) ->
vm.order = OrderService.getOrderId(vm.index)
Получения списка заказов - асинхронная функция, завёрнутая в промис. После выполнения в сервисе у тебя будет список заказов. Но функция getOrderId - синхронная и работает без промисов.
Это неправильно. Если хоть она функция в цепочке вызовов асинхронная и возвращает промис, то нужно выстроить цепочку промисов, и в контроллере в .then уже присваивать полученные данные.
В итоге, при загрузке страницы у тебя просто может не быть списка заказов.
Если взять мой сервис, то в контроллере надо так:
OrderController.$inject = ['OrderService'];
function OrderController(OrderService) {
var vm = this;
OrderService.getOrderId(vm.index)
.then((order) => {
vm.order = order;
})
.catch(() => {
vm.message = 'Заказ не найден';
});
}