0

OK, I have this code in a controller:

/* global myApp, ctrlRes */

'use strict';

myApp.controller('homeController',
    ['$scope','$state','homeDataService','companydetail',
        function ($scope, $state, homeDataService,companydetail) {

            var ctrlHome = this;
            ctrlHome.data = [];
            companydetail = [];

            ctrlHome.fetchHome = function () {
                //General Data
                homeDataService.getHomeData().then(function (result) {
                    ctrlHome.data.push(result.data.basedata.companyinfo);
                    companydetail.push(ctrlHome.data);

                    //We get list of whatever....
                    $scope.shows = homeDataService.list();
                    console.log("General: ", result.data.basedata);
                });
            };
            ctrlHome.fetchHome();


            //Redirects to a page sent into this function
            $scope.redirectToPage = function (pageToGoTo) {
                //if pageToGoTo = home, then route to /home!
                $state.go(pageToGoTo);
            };



}]);
//This is the details for HOME
myApp.controller('homeDetailController', 
    ['$scope','$state','$stateParams', 'homeDataService', 
        function($scope,$state,$stateParams, homeDataService) {

            var ctrlHmDets = this;
            ctrlHmDets.data = {};

            console.log("State Params: ", $state.params);

            //This is the part when the user selects a specifc itam
            $scope.selectedShow = homeDataService.find($stateParams.id);
            console.log("SelectedVal: " + $scope.selectedShow);
            ctrlHmDets.data.id = $scope.selectedShow;


 }]);

Now in that code, the coder in the service is below:

/* global myApp, _ */
var shows = [];

myApp.factory('homeDataService', function ($http, URL) {

    //Details for the Home Page
    shows = [{
        id: 1,
        title: 'Details 1',
        name: 'Home Details',
        description1: 'This is the detail content',
        description2: 'Description content for home details',
        detailtitle: 'This is the title for home 1',
        detailbody: 'This is detail for home 1'

    },{
        id: 2,
        title: 'Details 2',
        name: 'Home Details 2',
        description1: 'This is the detail content 2',
        description2: 'Description content for home details 2',
        detailtitle: 'This is the title for home 2',
        detailbody: 'This is detail for home 3'    
    },{
        id: 3,
        title: 'Details 3',
        name: 'Home Details 3',
        description1: 'This is the detail content 3',
        description2: 'Description content for home details 3',
        detailtitle: 'This is the title for home 3',
        detailbody: 'This is detail for home 3'   
    },{
        id: 4,
        title: 'Details 4',
        name: 'Home Details 4',
        description1: 'This is the detail content 4',
        description2: 'Description content for home details 4',
        detailtitle: 'This is the title for home 4',
        detailbody: 'This is detail for home 4'    
    }];

    var getHomeData = function () {
        return $http.get(URL + 'general-junk.json')
                .success(function (data) {
                    console.log("SUCCESS!");
                    console.log("The General Junk Home: " + data.basedata.companyinfo);
                    return data.basedata.companyinfo;
                })
                .error(function (e) {
                    console.log("He\'s dead Jim!", e);
                    return e;
                });

    };
    return {

        getHomeData: getHomeData,
        list: function () {

            return shows;

        }, //This is for DETAILs if we should have them
        find: function (id) {
            return _.find(shows, function (show) {
                return show.id === id;
            });
        }
    };
});

And finally in the app.js, my routing is thus:

/* global angular */

// Code goes here
var myApp;
myApp = angular.module("myApp", [
    "ui.router"

]);


myApp.config(function ($sceDelegateProvider) {

    $sceDelegateProvider.resourceUrlWhitelist(['self', '**']);


});
myApp.config(['$stateProvider', '$urlRouterProvider',
    function ($stateProvider, $urlRouterProvider) {

        // For any unmatched url, send to /route1
        $urlRouterProvider.otherwise("home");

        $stateProvider
                .state('home', {
                    url: "/home",
                    views: {
                        "mainHeader": {
                            templateUrl: "templates/mainHeader.html"

                        },
                        "mainNav": {
                            templateUrl: "templates/mainNav.html"

                        },
                        "mainContent": {
                            templateUrl: "templates/home.html"

                        },
                        "mainFooter": {
                            templateUrl: "templates/mainFooter.html"

                        }

                    }

                })
                //When we define a state as 'parentstatename.childstatename' the convention 
                //of simply adding the period when defining the state name tells UI-Router 
                //that the child state is nested under the parent state.

                //What is really great about nested views is that the list controller just 
                //has implementation details regarding the list and the detail controller 
                //is only concerned with showing details.

                //To show how decoupled these are we only need to change the routing 
                //configuration to not nest the details and we have two separate virtual 
                //pages (one for list and one for details). More specifically, we’ll 
                //change the state name 'shows.detail' to 'detail'.

                /*.state('detail', {
                *    url: "/detail/:id",
                *    templateUrl: 'templates/home-details.html'
                *    
                *})
                *
                *      And change the link to the state from 
                *      
                *      <a ui-sref="shows.detail({id: show.id})">{{show.name}}</a> 
                *      to 
                *      <a ui-sref="detail({id: show.id})">{{show.name}}</a>
                *      on the home-details.html page or whatever page you have that
                *      link on.
                */

                .state('home.detail', {
                    url: "/detail/:id",
                    templateUrl: 'templates/home-details.html',
                    controller: function($stateParams) {
                        $stateParams.id;
                    }

                })
                .state('about', {
                    url: "/about",
                    views: {
                        "mainAbout": {
                            templateUrl: "templates/about.html"
                        }
                    }

                });
    }]);

I'm using angular-ui-router.js and I have a

<div class="bodyStuff" ui-view></div>

The html page injected into that ui-view is simply this:

<h3>Hello World</h3>
<p>Some Text goes here</p>
<p><a ui-sref-active="selected" ui-sref="home.detail({id: show.id})">{{show.name}}</a>

<div class="detail" ui-view></div>

The interior DETAILS is this:

 <h2>Hi, I'm the detail title...</h2>
 <p>And this is what I'm all about!!!</p>

My question is: When I run the gamut through the code, $stateParams ALWAYS comes up UNDEFINED!!!

Meaning, when I call the "find" function in the service, the "id" argument is NEVER populated.

For reference, here's the link to where I got this...

Click to view Blog

I've seen $state.params and $stateParams. But nothing works.

I've done some research and found this too: Click to view Stackoverflow article

Thanks

UPDATE:

Below is the home.html that is injected into the ui-view on index.html

<section id="homePage">
<!-- injected Header 
<div id="header" ui-view="mainHeader"></div>-->
<!-- row -->
<div class="row" ng-controller="homeDetailController as ctrlHmDets">
    <!-- Angular Repeat... -->
    <div class="col-lg-3 col-sm-6" ng-repeat="show in shows">
        <div class="feature-widget">
            <article class="home-features-item hover">
                <div class="item-icon">
                    <i class="fa fa-html5"></i>
                </div>
                <div class="item-content">
                    <h3>{{show.title}}</h3>
                    <a ui-sref-active="selected" ui-sref="home.detail({id: show.id})">{{show.name}}</a>
                    <pre hidden="hidden">{{show | json}}</pre>
                    <p>{{show.description1}}</p>
                    <p>{{show.description2}}</p>
                </div>
            </article> <!-- home-features-item -->
        </div> <!-- feature-widget -->
    </div>
    <!-- End Repeat -->
    <div class="col-lg-12 col-sm-6">
        <!-- Detail View -->
        <div class="detail" ui-view></div>
        <!-- End Detail View --> 
    </div>
</div>

2
  • I am not able to find show variable in scope of your home controller. I am able to find shows. Are you having any ng-repeat on shows? Commented Aug 7, 2015 at 9:00
  • Yes, I'll update to show the repeat... Commented Aug 7, 2015 at 22:21

1 Answer 1

1

UPDATE ON 8-9-2015

OK, after tweaking this a bit more I found it truly wasn't working from the example below. Jump down to the bottom to TWEAKED UPDATE and See the way is REALLY WORKS!!!! *

YAHOO!!! I found the solution here.... Watch!

OK this is how you fix it and get $stateParams to work AND $state.params at the same time.

1st - IN YOUR APP.JS file do this in the route feature (code)

            .state('home', {
                url: "/home",
                views: {
                    "mainHeader": {
                        templateUrl: "templates/mainHeader.html"

                    },
                    "mainNav": {
                        templateUrl: "templates/mainNav.html"

                    },
                    "mainContent": {
                        templateUrl: "templates/home.html"

                    },
                    "mainFooter": {
                        templateUrl: "templates/mainFooter.html"

                    },
                    //Important $stateParams Gotcha
                    //
                    //In state controllers, the $stateParams object will only contain 
                    //the params that were registered with that state. So you will not 
                    //see params registered on other states, including ancestors.
                    //
                    //This is here to fix the problem...Instead, use a resolve statement in the parent route.
                    resolve: {
                        id: ['$stateParams', function ($stateParams) {
                                return $stateParams.id; //By putting this here... (STEP 1)
                            }]
                    }
                }
            })

Then jump down to the next .state:

STEP 2:

            .state('home.detail', {
                url: "/detail/:id",
                templateUrl: 'templates/home-details.html',
                controller: function ($stateParams) {
                    $stateParams.id;  //And this down here...(MATCH TO WHAT YOU DID ABOVE. HERE!!!)
                }
            })

And then run the code when you CLICK on the LINK you made in your MASTER page:

HERE...

<a ui-sref-active="selected" ui-sref="home.detail({id: show.id})">{{show.name}}</a>

The result is you get the answer you seek in the console.log, here...

           .state('home.detail', {
                url: "/detail/:id",
                templateUrl: 'templates/home-details.html',
                controller: function ($stateParams) {
                    $stateParams.id;  //id: "1", or "2" or "n"
                }
            })

WALA!!! It works. I'll put a plunker up for all to check out.

I need to shout out to the two links that I combined to do this:

1 - http://www.funnyant.com/angularjs-ui-router/ 2 - https://github.com/angular-ui/ui-router/wiki/URL-Routing#important-stateparams-gotcha

There, ah... I hope I've been able to help... Thanks, dhavalcengg for your insight and for giving me a "boot" to find the answer.

TWEAKED UPDATE:

1) OK, let's example the app.js...

    /* global angular, homeDetailsController */

    // Code goes here
    var myApp;
    myApp = angular.module("myApp", [
        "ui.router"

    ]);


    myApp.config(function ($sceDelegateProvider) {

        $sceDelegateProvider.resourceUrlWhitelist(['self', '**']);


    });
    myApp.config(['$stateProvider', '$urlRouterProvider',
        function ($stateProvider, $urlRouterProvider) {

            // For any unmatched url, send to /route1
            $urlRouterProvider.otherwise("home");

            $stateProvider
                    .state('home', {
                        url: "/home",
                        views: {
                            "mainHeader": {
                                templateUrl: "templates/mainHeader.html"

                            },
                            "mainNav": {
                                templateUrl: "templates/mainNav.html"

                            },
                            "mainContent": {
                                templateUrl: "templates/home.html"

                            },
                            "mainFooter": {
                                templateUrl: "templates/mainFooter.html"

                            },
                            //Important $stateParams Gotcha
                            //
                            //In state controllers, the $stateParams object will only contain 
                            //the params that were registered with that state. So you will not 
                            //see params registered on other states, including ancestors.
                            //
                            //This is here to fix the problem...Instead, use a resolve statement in the parent route.
                            resolve: {
                                id: ['$stateParams', function ($stateParams) {
                                        return $stateParams.id; //By putting this here...
                                    }]
                            }
                        }
                    })
                    .state('home.detail', {
                        cache: false,
                        url: "/detail/:id",
                        views: {
                            "details": {
                                templateUrl: 'templates/home-details.html',
                                controller: "homeDetailController"
                            }
                        }
                    })
                    .state('about', {
                        url: "/about",
                        views: {
                            "mainAbout": {
                                templateUrl: "templates/about.html"
                            }
                        }

                    });
        }]);

    console.log("Host name is: " + document.location.hostname);

    if (document.location.hostname === "localhost") {
        myApp.constant('URL', '/mywebsite/js/json/');
    } else if (document.location.hostname === "mywebsite.net" || "www.mywebsite.net") {
        myApp.constant('URL', '/js/json/');
    } else {
        myApp.constant('URL', '/mywebsite/js/json/');
    }


    //Registering the company for the key achievements
    //This defines and initializes a value service called company and assigns it an 
    //object with some default values.

    myApp.constant("companydetail", {
        "data": {
            "company": []

        }
    });

2) now the CONTROLLERS.JS

    /* global myApp, ctrlRes */

    'use strict';

    myApp.controller('homeController',
            ['$scope', '$state', 'homeDataService', 'companydetail',
                function ($scope, $state, homeDataService, companydetail) {

                    var ctrlHome = this;
                    ctrlHome.data = [];
                    companydetail = [];

                    ctrlHome.fetchHome = function () {
                        //General Data
                        homeDataService.getHomeData().then(function (result) {
                            ctrlHome.data.push(result.data.basedata.companyinfo);
                            companydetail.push(ctrlHome.data);

                            //We get list of whatever....
                            $scope.shows = homeDataService.list();
                            console.log("General: ", result.data.basedata);
                        });
                    };
                    ctrlHome.fetchHome();


                    //Redirects to a page sent into this function
                    $scope.redirectToPage = function (pageToGoTo) {
                        //if pageToGoTo = home, then route to /home!
                        $state.go(pageToGoTo);
                    };
                }]);
    //This is the details for HOME
    myApp.controller('homeDetailController',
            ['$scope', '$stateParams', 'homeDataService',
                function ($scope, $stateParams, homeDataService) {


                var ctrlHmDets = this;
                    ctrlHmDets.data = {};
                    ctrlHmDets.data.paramsId = $stateParams.id;
                    //Call the service
                    homeDataService.find($stateParams.id);

                    console.log("From stateParams.id: " + $stateParams.id);

                    //Set the selected value
                    $scope.selectedShow = ctrlHmDets.data.id = $stateParams.id;
                    console.log("SelectedVal: " + $scope.selectedShow);

                }]);
    //This is ABOUT
    myApp.controller('aboutController', ['$scope', '$state', 'aboutDataService',
        function (aboutDataService) {
            var ctrlAbout = this;

            ctrlAbout.content = [];

            ctrlAbout.fetchHome = function () {
                //General Data
                aboutDataService.getAboutData().then(function (result) {
                    ctrlAbout.content = result.data.dets.basedata;
                    console.log("About: ", result.data.dets.basedata);
                });
            };
            ctrlAbout.fetchAbout();
        }]);

3) Next the SERVICES.JS...

    /* 
     * To change this license header, choose License Headers in Project Properties.
     * To change this template file, choose Tools | Templates
     * and open the template in the editor.
     */
    /* global myApp, _ */
    var shows = [];

    myApp.factory('homeDataService', function ($http, URL) {

        //Details for the Home Page
        shows = [{
            id: 1,
            title: 'Details 1',
            name: 'Home Details',
            description1: 'This is the detail content',
            description2: 'Description content for home details',
            detailtitle: 'This is the title for home 1',
            detailbody: 'This is detail for home 1'

        },{
            id: 2,
            title: 'Details 2',
            name: 'Home Details 2',
            description1: 'This is the detail content 2',
            description2: 'Description content for home details 2',
            detailtitle: 'This is the title for home 2',
            detailbody: 'This is detail for home 3'    
        },{
            id: 3,
            title: 'Details 3',
            name: 'Home Details 3',
            description1: 'This is the detail content 3',
            description2: 'Description content for home details 3',
            detailtitle: 'This is the title for home 3',
            detailbody: 'This is detail for home 3'   
        },{
            id: 4,
            title: 'Details 4',
            name: 'Home Details 4',
            description1: 'This is the detail content 4',
            description2: 'Description content for home details 4',
            detailtitle: 'This is the title for home 4',
            detailbody: 'This is detail for home 4'    
        }];

        var getHomeData = function () {
            return $http.get(URL + 'general-junk.json')
                    .success(function (data) {
                        console.log("SUCCESS!");
                        console.log("The General Junk Home: ", data.basedata.companyinfo);
                        return data.basedata.companyinfo;
                    })
                    .error(function (e) {
                        console.log("He\'s dead Jim!", e);
                        return e;
                    });

        };
        return {

            getHomeData: getHomeData,
            list: function () {

                return shows;

            }, //This is for DETAILs if we should have them
            find: function (id) {
                return _.find(shows, function (show) {
                    return show.id === id;
                });
            }
        };
    });

    myApp.factory('aboutDataService', function ($http, URL) {
        var getAboutData = function () {
            return $http.get(URL + 'general-junk.json')
                    .success(function (data) {
                        console.log("SUCCESS!");
                        console.log("The About Stuff: " + data);
                        return data;
                    })
                    .error(function (e) {
                        console.log("He\'s dead Jim!", e);
                        return e;
                    });

        };
        return {
            getAboutData: getAboutData
        };
    });

5) now the INDEX.HTML Page:

    <!DOCTYPE html>
    <html id="ng-app" lang="en" ng-app="myApp">

        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">

            <title>myWesite.net</title>

            <!-- CSS -->
            <link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
            <link href="css/font-awesome.min.css" rel="stylesheet" media="screen">
            <!-- <link href="css/style.min.css" rel="stylesheet" media="screen"> -->
            <link href="css/style.css" rel="stylesheet" media="screen">
            <link href="css/wp-custom.css" rel="stylesheet" type="text/css"/> <!-- This is my custome CSS leave it out -->

            <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
            <!--[if lt IE 9]>
                <script src="js/html5shiv.js"></script>
                <script src="js/respond.min.js"></script>
            <![endif]-->
            <base href="index.html">
            <script src="js/jquery/jquery-1.10.2.min.js"></script>

            <script src="js/angular/angular.js" type="text/javascript"></script>
            <script src="js/angular/angular-ui-router.min.js" type="text/javascript"></script>

        </head>


        <body id="index">

            <div class="container" ng-controller="homeController as ctrlHome">
                <!-- Nav UI View -->
                <nav id="mainbar" class="hidden-xs" ui-view="mainNav"></nav>
                <!-- Nav UI View -->
                <div id="wrap">
                    <!-- injected header content -->
                    <div id="header" ui-view="mainHeader"></div>
                    <!-- injected main content -->
                    <div id="bodyStuff" ui-view="mainContent"></div>
                    <!-- End of Injected Content-->
                </div> <!-- wrap -->
                <footer id="footer" ui-view="mainFooter"></footer>
            </div> <!-- container -->
            <!-- underscore -->
            <script src="js/underscore.js/underscore.js" type="text/javascript"></script>
            <!-- Scripts -->
            <script src="js/bootstrap/bootstrap.min.js"></script>

            <!-- Angular -->
            <script src="js/angular/app.js" type="text/javascript"></script>
            <script src="js/angular/controllers/controllers.js" type="text/javascript"></script>
            <script src="js/angular/directives/directives.js" type="text/javascript"></script>
            <script src="js/angular/services/data-service.js" type="text/javascript"></script>


        </body>

    </html>

6) Now let's examine the HOME.HTML file

    <section id="homePage">
        <!-- injected Header 
        <div id="header" ui-view="mainHeader"></div>-->
        <!-- row -->
        <div class="row">
            <!-- Angular Repeat... -->
            <div class="col-lg-3 col-sm-6" ng-repeat="show in shows">
                <div class="feature-widget">
                    <article class="home-features-item hover">
                        <div class="item-icon">
                            <i class="fa fa-html5"></i>
                        </div>
                        <div class="item-content">
                            <h3>{{show.title}}</h3>
                            <a ui-sref-active="selected" ui-sref="home.detail({id: show.id})">{{show.name}}</a>
                            <p>{{show.description1}}</p>
                            <p>{{show.description2}}</p>
                            <pre hidden="hidden">{{show | json}}</pre>
                        </div>
                    </article> <!-- home-features-item -->
                </div> <!-- feature-widget -->
            </div>
            <!-- End Repeat -->
            <div class="col-lg-12 col-sm-6">
                <!-- Detail View -->
                <div class="detail" ui-view="details"></div>
                <!-- End Detail View --> 
            </div>
        </div>
    </section>

7) and finally the HOME-DETAILS.HTML file...

    <h3>{{shows[selectedShow - 1].detailtitle}}</h3>
    <p>{{shows[selectedShow - 1].detailbody}}</p>
    <pre hidden="hidden">{{selectedShow - 1 | json}}</pre>

The result is nothing short of beautiful.

This is an enhancement to the article I referenced above from Craig Craig McKeachiein's Blog and Podcast. He deserves the credit here for inspiring me.

This is from a template on CreativeMarket that I wanted to add Angular to.

Sign up to request clarification or add additional context in comments.

2 Comments

impressive rant
Rant? I wasn't "ranting". But I did, however, figure it all out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.