F
F
fantom00052016-02-21 10:21:55
JavaScript
fantom0005, 2016-02-21 10:21:55

Information does not appear in the directive, what should I do?

Hello. I have a service that loads a list of orders from the server. I decided to display them through the directive. But here's the problem: when loading orders, I pass them to the controller, but they are not displayed in the templates.
PS. sorry for coffeescript
service itself

OrderS = ($http,$q,AuthService) ->
  vm = @

  vm.orders = []

  vm.getOrders = ->
    if AuthService.authorized
      deferred = $q.defer()
      $http.get('/dashboard/api/v1/orders/')
      .success (response, status, headers, config) ->
        if status == 200
          vm.orders = response
        deferred.resolve(response, status, headers, config)
      .error (response, status, headers, config) ->
        deferred.reject(response, status, headers, config)
      return deferred.promise
    else
      return null

  vm.getOrderId = (id) ->
    if vm.orders
      for item in vm.orders
        if item.id.toString() == id.toString()
          return item
    else
      return null

  vm

angular.module('dashboardApp').service 'OrderService', [
  '$http'
  '$q'
  'AuthService'
  OrderS
]

And a directive with a controller
OrderDirective = () ->
  restrict : 'E'
  controller : OrderCtrl
  controllerAs : "order"
  transclude: true
  scope:
    index: "@index"
  templateUrl: '/static/store/templates/order.html'
  link: (scope, element, attr, ctrl) ->
    ctrl.index = attr.index
    ctrl.setOrder()

angular.module('dashboardApp').directive 'order', [
  OrderDirective
]


OrderCtrl = (OrderService,$scope) ->
  vm = @

  vm.order = {}
  vm.index = ""

  vm.setOrder = (id) -> 
    vm.order = OrderService.getOrderId(vm.index)

  $scope.$watch(
    -> OrderService.getOrderId(vm.index)	
    (newValue) -> vm.setOrder(vm.index)
  )

  vm

angular.module('dashboardApp').controller 'OrderCtrl', [
  'OrderService'
  '$scope'
  LoginCtrl
]

Template is big, I won't throw it away. Let's just say: {{order.order.id}}.
Please help guys. I've already broken my brain. Thanks!!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
B
bromzh, 2016-02-21
@bromzh

Before writing something further in Angular, I advise you to study the styleguide and follow it.
Such things are especially bad:
1) using .success/.error instead of .then in $http; They have been deprecated a long time ago. Only .then.
2) creation of extra deferred-objects. the .then() method will return the promise anyway.
3) in the .getOrders method of your service, a promise is returned in one case, and simply null in the other. always return a promise. just where everything is bad, you need to do reject
4) save the list in the service, and then look for an element by id in it is not a good idea. you should always request fresh data from the server
. In general, your service should look something like this:

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();
            });
        
    }
}

Well, if you do not work with the DOM, the link function is not needed, the controller directive is enough.
Well, the answer to your question lies here:
vm.setOrder = (id) -> 
    vm.order = OrderService.getOrderId(vm.index)

Getting a list of orders is an asynchronous function wrapped in a promise. After completing the service, you will have a list of orders. But the getOrderId function is synchronous and works without promises.
It is not right. If at least it is a function in the call chain is asynchronous and returns a promise, then you need to build a chain of promises, and in the controller in .then already assign the received data.
As a result, when loading the page, you simply may not have a list of orders.
If you take my service, then in the controller you need to do this:
OrderController.$inject = ['OrderService'];
function OrderController(OrderService) {
    var vm = this;

    OrderService.getOrderId(vm.index)
        .then((order) => {
            vm.order = order;
        })
        .catch(() => {
            vm.message = 'Заказ не найден';
        });
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question