0

I am using UI-Router for an Angular app. I can't seem to find what I am doing wrong. I am also not getting any errors which is making it really difficult for me to debug. Followed the docs as well and I am following their steps. My controller function is working when I don't nest it in a child view. Can someone please direct me to what I am doing wrong? Thanks in advance!

APP.JS

'use strict';

var app = angular.module('americasTopStatesApp', ['ui.router', 'ngAutocomplete']);

app.run(function($state, $rootScope) {
    $rootScope.$state = $state;
});

app.config(function($stateProvider, $urlRouterProvider) {

    $urlRouterProvider
    .otherwise('/home');

    $stateProvider
    //HOME
    .state('home', {
        url: '/home',
        templateUrl: './app/views/homeTmpl.html',
        controller: 'homeCtrl'
    })
    //RANKINGS
    .state("rankings", {
        url: "/rankings",
        templateUrl: './app/views/rankingsTmpl.html',
        controller: 'rankingsCtrl'
    })  
        // RANKINGS CHILDREN
        .state('rankings.data', {
            url: '/data',
            templateUrl: './app/views/rankingsDataTmpl.html',
            controller: 'rankingsCtrl',
            parent: 'rankings'
        })
});

CONTROLLER rankingsCtrl

'use strict';

app.controller('rankingsCtrl', function($scope, rankingsService) { //Start Controller

    // ***********************************************
    // *************** GET LATEST DATA ***************
    // ***********************************************  
    $scope.getAllStateRankings = function() {
        rankingsService.getStateRankingsData().then(function(data) {
            $scope.showRankings = true;

            // console.log("Contoller Data", data);
            $scope.states = data;
        });
    };
    $scope.showRankings = false;
    $scope.getAllStateRankings();

}); //End Controller

PARENT VIEW rankingsTmpl.html

<div class="rankings-heading">
    <h1>America's Top States</h1>
    <button ng-click="getAllStateRankings()">
        <a ui-sref="rankings.data" id="data" class="btn">Data</a>
    </button>
</div>

</div ui-view></div>

Child View (Nested ui-view) rankingsDataTmpl.html

<div class="rankings-container" ng-show="showRankings">

    <div class="panel panel-primary" ng-repeat='state in states'>
        <div class="panel-heading">
            <h3 class="panel-title">{{state.state}}</h3>
        </div>
        <div class="panel-body">
            Economy: {{state.economy}}<br>
            Capital Access: {{state.accessToCapital}}<br>
            Business: {{state.business}}<br>
            Cost of living: {{state.costOfLiving}}<br>
        </div>
    </div>
</div>

Screen Shot

enter image description here

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
Mihir Patel
  • 2,202
  • 3
  • 23
  • 36

1 Answers1

1

There is a working plunker

In this case, when we have parent child and angular's UI-Router, we should not use solution based on

parent and child has same controller. // WRONG approach

Because they in fact do have JUST same type. The instance of that type 'rankingsCtrl' in runtime is different.

What we need is:

How do I share $scope data between states in angularjs ui-router?

scope inheritance, driven by reference object, e.g. $scope.Model = {}

There is adjusted controller:

.controller('rankingsCtrl', ['$scope', function($scope) {

    $scope.Model = {};
    $scope.getAllStateRankings = function() {
      //rankingsService.getStateRankingsData().then(function(data) {
        $scope.Model.showRankings = true;

        // console.log("Contoller Data", data);
        $scope.Model.states = data;
      //});
    };
    $scope.Model.showRankings = false;
    $scope.getAllStateRankings();

}])

At the end, child can have different controller with its own logic for the child view:

.state("rankings", {
  url: "/rankings",
  templateUrl: 'app/views/rankingsTmpl.html',
  controller: 'rankingsCtrl'
})
// RANKINGS CHILDREN
.state('rankings.data', {
  url: '/data',
  templateUrl: 'app/views/rankingsDataTmpl.html',
  controller: 'rankingsChildCtrl',
  parent: 'rankings'
})

Also, the parent view should have fixed div:

// wrong
</div ui-view></div>
// starting tag
<div ui-view></div>

Check it here in action

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • Great to see that, really! Enjoy mighty UI-Router, sir ;) – Radim Köhler Sep 05 '15 at 04:51
  • Thank you for sparking me about inherited scopes within nested views in ui-router. I am reading tons, but still slightly off the track. I created what you had asked me to but I can't see any data still. Here is my plunkr- http://plnkr.co/edit/sNx2otsOdAx1XyxGuTmx?p=catalogue – Mihir Patel Sep 05 '15 at 15:45
  • Not sure what I could do for you... ;( is my plunker not working for you? If you have some idea how I could assist.. let me know. If I'll be able, I at least try to help – Radim Köhler Sep 05 '15 at 15:47
  • Yours is working, but when I implement it on my code, it doesn't work. @radimkohler- created a plunkr for you to see my code. I thought I knew ui-router, but now I really have to dig deeper and study nested views and inheritance scopes. – Mihir Patel Sep 05 '15 at 15:52
  • Ooops I missed that plunker link previously... give me few secs to check if I can help... – Radim Köhler Sep 05 '15 at 15:54
  • So, there is forked and ***Really working but significantly changed version*** http://plnkr.co/edit/T6RWW2Z4t0EmTcSnBoE6?p=preview It is hard to describe what all I had to change... just observe it ;) hope this will help you ;) – Radim Köhler Sep 05 '15 at 16:15
  • man you are great! Thank you so much for your help! I was not passing Model.showRankings on my child view. I learned about inherited scope and runtime load. Thank you for dropping some knowledge. Hope you have a great rest of the day!!! @RadimKohler – Mihir Patel Sep 05 '15 at 16:59
  • If that helped, great, really ;) Enjoy amazing UI-Router, sir! – Radim Köhler Sep 05 '15 at 17:00