2

I am very beginner in Angular.js, I am using the Ui-router framework for routing. I can make it work upto where I have no parameters in the url. But now I am trying to build a detailed view of a product for which I need to pass the product id into the url.

I did it by reading the tutorials and followed all the methods. In the tutorial they used resolve to fetch the data and then load the controller but I just need to send in the parameters into the controllers directly and then fetch the data from there. My code looks like below. when I try to access the $stateParams inside the controller it is empty. I am not even sure about whether the controller is called or not. The code looks like below.

(function(){
    "use strict";
    var app = angular.module("productManagement",
                            ["common.services","ui.router"]);
    app.config(["$stateProvider","$urlRouterProvider",function($stateProvider,$urlRouterProvider)
        {
            //default
            $urlRouterProvider.otherwise("/");

            $stateProvider
                //home
                .state("home",{
                    url:"/",
                    templateUrl:"app/welcome.html"
                })
                //products
                .state("productList",{
                    url:"/products",
                    templateUrl:"app/products/productListView.html",
                    controller:"ProductController as vm"
                })
                //Edit product
                .state('ProductEdit',{
                    url:"/products/edit/:productId",
                    templateUrl:"app/products/productEdit.html",
                    controller:"ProductEditController as vm"
                })
                //product details
                .state('ProductDetails',{
                    url:"/products/:productId",
                    templateUrl:"app/products/productDetailView.html",
                    Controller:"ProductDetailController as vm"
                })
        }]
    );
}());

this is how my app.js looks like. I am having trouble on the last state, ProdcutDetails.

here is my ProductDetailController.

(function(){
    "use strict";
    angular
        .module("ProductManagement")
        .controller("ProductDetailController",
                    ["ProductResource",$stateParams,ProductDetailsController]);
        function ProductDetailsController(ProductResource,$stateParams)
        {
            var productId = $stateParams.productId;
            var ref = $this;
            ProductResource.get({productId: productId},function(data)
            {
                console.log(data);
            });
        }
}());

NOTE : I found lot of people have the same issue here https://github.com/angular-ui/ui-router/issues/136, I can't understand the solutions posted their because I am in a very beginning stage. Any explanation would be very helpful.

Vignesh
  • 1,045
  • 2
  • 17
  • 34

2 Answers2

1

The params in controller definition array should be strings

["ProductResource", "$stateParams"...

This should properly help IoC to inject the $stateParams

And even better:

// the info for IoC
// the style which you will use with TypeScript === angular 2.0
ProductDetailsController.$inject = ["ProductResource", "$stateParams"];

// this will just map controller to its name, parmas are defined above
.controller("ProductDetailController", ProductDetailsController);
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • I did this very first but it was not working, so I tried without the quotes. there are no errors too in the controller in both ways. How can I debug.. – Vignesh Mar 31 '15 at 07:51
  • if I put an alert at the first line of the controller function it is not showing up. I think there is some other problem too.. – Vignesh Mar 31 '15 at 07:53
  • yeah. I'm trying like the IOC – Vignesh Mar 31 '15 at 07:54
  • but where should i do the injection inside the controller's IIFE? – Vignesh Mar 31 '15 at 07:54
  • 1
    Check this **working plunker http://plnkr.co/edit/0AuoAiB784qtWEhtBDF9?p=preview** I created for your. That should help you to observe how to – Radim Köhler Mar 31 '15 at 07:59
  • Why do not use the standard approach for controller implementation? For example: `.controller('GreetingController', ['$scope', function($scope) { $scope.greeting = 'Hola!'; }]);` – okanozeren Mar 31 '15 at 08:00
  • @nerezo I am not aware of which one is regular approach. I did the same for the product list and its working fine. why passing an url parameter should be this difficult?? you can tell me what is regular approach – Vignesh Mar 31 '15 at 08:01
  • The point is, this is standard approach ;) ;) **[$inject Property Annotation](https://docs.angularjs.org/guide/di)**. Even more, this is the way which you will see with TypeScript. And even more, this will be the main way how to do it in angualr 2.0 – Radim Köhler Mar 31 '15 at 08:02
  • @Vignesh I mean standard for controller implementation I provided as example. – okanozeren Mar 31 '15 at 08:04
  • oh, with the scope injection? I'll try that @nerezo – Vignesh Mar 31 '15 at 08:46
  • @RadimKöhler I tried like this still not working. I must have done anything wrong I think. even the alert was not showing up. – Vignesh Mar 31 '15 at 09:09
  • I've spent so much time on your issue, and I overseen the "BUG" ;) Now in my brand new and complete answer... you should have all you need – Radim Köhler Mar 31 '15 at 09:42
1

I created working plunker here

There is state configuration

$urlRouterProvider.otherwise('/home');

// States
$stateProvider
    //home
    .state("home",{
        url:"/",
        templateUrl:"app/welcome.html"
    })
    //products
    .state("productList",{
        url:"/products",
        templateUrl:"app/products/productListView.html",
        controller:"ProductController as vm"
    })
    //Edit product
    .state('ProductEdit',{ 
        url:"/products/edit/:productId",
        templateUrl:"app/products/productEdit.html",
        controller:"ProductEditController as vm"
    })
    //product details
    .state('ProductDetails',{
        url:"/products/:productId",
        templateUrl:"app/products/productDetailView.html",
        controller:"ProductDetailController as vm"
    })

There is a definition of above used features

.factory('ProductResource', function() {return {} ;})
.controller('ProductController', ['$scope', function($scope){
  $scope.Title = "Hello from list";
}])
.controller('ProductEditController', ['$scope', function($scope){
  $scope.Title = "Hello from edit";
}])
.run(['$rootScope', '$state', '$stateParams',
  function ($rootScope, $state, $stateParams) {
    $rootScope.$state = $state;
    $rootScope.$stateParams = $stateParams;
}])
.controller('ProductDetailController', ProductDetailsController)

function ProductDetailsController ($scope, ProductResource, $stateParams)
{
    $scope.Title = "Hello from detail";
    var productId = $stateParams.productId;
    //var ref = $this;
    console.log(productId);
    //ProductResource.get({productId: productId},function(data)    {    });
    return this;
}
ProductDetailsController.$inject = ['$scope', 'ProductResource', '$stateParams'];

Check it here

But do you know what is the real issue? Just one line in fact, was the trouble maker. Check the original state def:

.state('ProductDetails',{
    ...
    Controller:"ProductDetailController as vm"
})

And in fact, the only important change was

.state('ProductDetails',{
    ...
    controller:"ProductDetailController as vm"
})

I.e. controller instead of Controller (capital C at the begining)

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • Thanks for spending your time for me.. Radim Kohler. The problem was a typo. in the State definition I used Controller instead of controller. Just now I found that out and its working now. – Vignesh Mar 31 '15 at 09:46
  • can I move this state definitions to a diffrent file and mention it here? in case of a bigger app? – Vignesh Mar 31 '15 at 09:47
  • 1
    You can.. the same I do have. Many many files... just properly use module once for creating with array, later just with a name to inject all the stuff. Good luck with mighty UI-Router ;) – Radim Köhler Mar 31 '15 at 09:48