2

I am having some trouble getting to the controller for my state param. I am using the correct state to link to the next view.

 <td><a ui-sref="orders({customerId: cust.id})">View Orders</a></td>

In my config file I am referencing the state that name and the route params. I commented out the resolve object for now. My goal is to get into the controller then pass the correct data. Notice that I am using controllerAs

My initial thought was ({customerId: ctrl.cust.id }) However that did not change the url route. The url is changing to match the url name but is not connecting to the controller and is not giving me the view.

    (function() {
        'use strict';

        angular
            .module('app.orders')
            .config(config);

        function config($stateProvider) {
            $stateProvider
                .state('orders',{
                    // params: {customerid: null},
                    url:'/customers:customerId', 
                    templateUrl: './components/orders/orders.html',
                    controller: 'OrdersController',
                    controllerAs: 'ctrl',
                    resolve: {
                    customerFactory: 'customerFactory',
                    customerInfo: function( customerFactory, $stateParams) {
                    return customerFactory.getCustomers($stateParams.id);
                }

            }

************** my main problem is the resolve. This is blocking me from getting into the next controller. *****************

                    resolve: {
                        customerId:[ '$stateParams','customerFactory', function( $stateParams, customerFactory) {
                             return customerFactory.getCustomers($stateParams.id);
                         }]
                     }
            })
        };
})();

For now my controller is very small. I just want to connect to it. I have checked my networks tab and see GET for the files.

  (function() {
    // 'use strict';
    angular
        .module('app.orders')
        .controller('OrdersController', OrdersController);

    function OrdersController($stateParams) {
        console.log('in');
            var vm = this;
            vm.title = "Customer Orders";
            vm.customer = null;
    }
}());

I have referenced my module in the main javascript file.

   (function () {
    'use strict';

    angular.module('app', ['app.services',
        'app.customers',
        'app.orders','ui.router']);
})();

When I comment out the resolve I am able to access the controller. So I know the problem is in the resolve. Here is my service. I am making a request to a Json file with $http request and using .then

Updates Here is my refactored service call I am getting back the correct customer in the console each time.

  (function() {
    angular
        .module('app.services',[])
        .constant('_', window._)
        .factory('customersFactory', customersFactory);

    function customersFactory($http, $log) {

        return {
            getCustomers: getCustomers,
            getCustomer: getCustomer
        };
        function getCustomers(){
            return $http.get('./Services/customers.json',{catch: true})
                .then(getCustomerListComplete)
                .catch(getCustomerListFailed);

                function getCustomerListComplete(response) {
                    console.log('response.data',response.data);
                    return response.data;
                }

                function getCustomerListFailed(error) {
                    console.log('error', error);
                }
        }

        function getCustomer(id) {
            var url = './Services/customers.json';
            return $http.get(url, {
                catch: true
            })
            .then(function(response) {
                console.log('promise id',id);
                var data = response.data;
                for(var i =0, len=data.length;i<len;i++) {
                    console.log('data[i].id',data[i].id);
                    if(data[i].id === parseInt(id)) {
                        console.log('data[i]', data[i]);
                        return data[i];
                    }
                }
            })
        }
    }
}());
Winnemucca
  • 3,309
  • 11
  • 37
  • 66

2 Answers2

3

There is a working example with your code

It is very hard to guess what is wrong. Based on suggestion I gave you here Have a expression error in ui-sref ... your code seems to be completely valid.

I placed your stuff into this app.orders.js file (the ONLY change is templateUrl path, just for plunker purposes):

angular
  .module('app.orders', ['ui.router'])


'use strict';

angular 
    .module('app.orders')
    .config(['$stateProvider', config]); 

//config.$inject = ['$stateProvider'];
function config($stateProvider) {
    $stateProvider
        .state('orders',{
            // params: {customerid: null},
            url:'/customers:customerId', 
            //templateUrl: './components/orders/orders.html',
            templateUrl: 'components/orders/orders.html',
            controller: 'OrdersController',
            controllerAs: 'ctrl'
            // resolve: {
            //     customerId:[ '$stateParams','customerFactory', function( $stateParams, customerFactory) {
            //         return customerFactory.getCustomers($stateParams.id);
            //     }]
            // }
    })
};


// 'use strict';
angular
    .module('app.orders')
    .controller('OrdersController', OrdersController);

OrdersController.$inject = ['$stateParams'];
function OrdersController($stateParams) {
    console.log('in');
        var vm = this;
        vm.title = "Customer Orders " + $stateParams.customerId;
        vm.customer = null;
}

And this is the working template components/orders/orders.html:

<div >
  <h3>current state name: <var>{{$state.current.name}}</var></h3>

  <h5>title</h5>
  <pre>{{ctrl.title}}</pre>
  ...

When I call it like this:

<li ng-repeat="cust in [{id:1}, {id:2}]"
    ><a ui-sref="orders({customerId: cust.id})">View Orders - cust ID == {{cust.id}}</a>
</li>

Check it in action here

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • @HarshMehta, why would you think that it is wrong? I checked and working.. *(small note, most of European names are First is FirstName, Last is LastName)* – Radim Köhler Sep 09 '15 at 06:32
  • @Steve k,i also found no phishy things in existing code.Might be some problem within absolute state redirection.Have you checked generated html from ui-sref ? is it according to your expectation, See [this](https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref) – road2victory Sep 09 '15 at 07:32
  • @RadimKöhler. Thanks for your help I know you tried to help me with this before. The problem that I ran into was using the views {} that I created on the customer route. I striped that out of my code I will have to read more on the absolute routing to understand how to use views correctly in this relationship . – Winnemucca Sep 09 '15 at 15:40
1

So, whil my previous answer was about make the state working without resolve, now we will observe few adjustments (and one fix) to make even resolve working.

There is a working plunker, extending the previous one.

FIX

The only fix, the most important change come from this definition:

angular
    .module('app.services',[])
    .factory('customersFactory', customersFactory);

see the plural in the factory name, the 'customersFactory'. While here:

...my main problem is the resolve. This is blocking me from getting into the next controller....

resolve: {
  customerId:[ '$stateParams','customerFactory', function( $stateParams, customerFactory) {
    return customerFactory.getCustomers($stateParams.id);
  }]
}

we ask for 'customerFactory' (singular, no s in the middle)

Few improvements:

So, this would be our adjusted state def:

$stateProvider
    .state('orders',{
        // INTEGER is here used to later easily use LO_DASH
        url:'/customers{customerId:int}', // int is the type
        templateUrl: './components/orders/orders.html',
        controller: 'OrdersController',
        controllerAs: 'ctrl',
        resolve: {
          // wrong name with 's'
          //customerId:[ '$stateParams','customerFactory', 
          // we use customer, because we also changed the factory 
          // implementation - to return customer related to 
          // $statePrams.customerId
          customer:[ '$stateParams','customersFactory', 
            function( $stateParams, customersFactory) {
              return customersFactory
                //.getCustomers($stateParams.id)
                .getCustomer($stateParams.customerId)
                ;
            }]
          }
})

Now, this is our adjusted factory, and its new method getCustomer

angular
  .module('app.services', [])
  .factory('customersFactory', customersFactory);

customersFactory.$inject = ['$http', '$log', '$q', '$stateParams'];

function customersFactory($http, $log, $q, $stateParams) {

  return {
    getCustomers: getCustomers,
    getCustomer: getCustomer
  };

  function getCustomers() {
    // see plunker for this, or above in question
  }

  // new function
  function getCustomer(id) {
    var url = "customer.data.json";
    return $http
      .get(url, {
        catch: true
      })
      .then(function(response){
        var data = response.data;
        var customer = _.find(data, {"id" : id});
        return customer;
      })
      ;
  }
}

this is our data.json:

[
  {
    "id" : 1, "name": "Abc", "Code" : "N1"
  },
  {
    "id" : 2, "name": "Def", "Code" : "N22"
  },
  {
    "id" : 3, "name": "Yyz", "Code" : "N333"
  }
] 

And here we have controller:

OrdersController.$inject = ['$stateParams', 'customer'];
function OrdersController($stateParams, customer) {
    console.log('in');
        var vm = this;
        vm.title = "Customer Orders " + $stateParams.customerId;
        vm.customer = customer;
}

a view to show customer

<h3>customer</h3>
<pre>{{ctrl.customer | json}}</pre>

Check it here in action

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • Thanks again. You have really been helpful. I caught the typo and fixed it. I inject lodash as a constant (not sure if that is necessary). Inside of the promise for getCustomer I am still get all instances. My impression from _.find is to find the match to the given id passed in. However, that seems to return undefined. – Winnemucca Sep 14 '15 at 16:29
  • Could you change my plunker to show the issue? I am ready to assist if you want... PLEASE - my implementation with lo-dash is just to demonstrate the GetById(id) .. in that example. Its up to you, how to get by ID. It could be special API service method, directly consuming ID and returning just one object. My approach was just to make it simple... – Radim Köhler Sep 14 '15 at 16:30
  • Ok, here is how I set up my service. I am getting the correct customer Info in the service which is exactly what I want. I am trying to get it to the controller. However, I am getting undefined. http://plnkr.co/edit/4JOSaJ?p=info – Winnemucca Sep 14 '15 at 17:30
  • 1
    I have fixed the my resolve!!! I did not properly reference customer in the controller. Thank you for the help @Radim. – Winnemucca Sep 14 '15 at 17:37
  • Great to see that progress. Good luck Steve with angular and mostly with UI-Router ;) – Radim Köhler Sep 14 '15 at 17:48