0

In my Angular app, I have the following route structure:

.state('mapping', {
    url: '/mapping',
    templateUrl: 'app/components/mapping/mapping.html',
    controller: 'MapCtrl as map',
    abstract: true,
    authenticate: true
})
.state('mapping.all', {
    url: '',
    templateUrl: 'app/components/mapping/partials/all.html',
    authenticate: true
})
.state('mapping.project', {
    url: '/:projectName',
    templateUrl: 'app/components/mapping/partials/project.html',
    controller: 'ProjectCtrl as proj',
    authenticate: true
})

When accessing the mapping state, mapping.all loads by default. It basically shows a list of projects which link to the mapping.project state, as such:

<a ui-sref="mapping.project({projectId: project.id, projectName: project.name})">...</a>

I want to call the ProjectCtrl when I access mapping.project in order to load the necessary data, but it never even gets loaded. In the snippet below which includes only relevant data, the alert message never pops up:

angular
    .module('watera')
    .controller('ProjectCtrl', Controller);

Controller.$inject = ['$stateParams', 'UserFactory', 'ProjectFactory'];

function Controller($stateParams, UserFactory, ProjectFactory) {
    var proj = this;

    activate();

    function activate() {
        alert('1');
    }
}

The js file is correctly linked and the controller is named correctly. The <div ui-view></div> element is placed within mapping.html, as seen below:

<div id="ribbon" class="no-print">
    <div class="container-fluid">
        <div class="row">
            <div class="col-xs-12">
                <strong>Mapping</strong>
                <p class="text-muted">In this section...</p>
            </div>
        </div>
    </div>
</div>

<div ui-view></div>

Why is this controller not loading?

EDIT: It gets weirder, I switched the structure to:

.state('mapping', {
    url: '/mapping',
    templateUrl: 'app/components/mapping/mapping.html',
    abstract: true,
    authenticate: true
})
.state('mapping.all', {
    url: '',
    templateUrl: 'app/components/mapping/partials/all.html',
    controller: 'MapCtrl as map',
    authenticate: true
})
.state('mapping.project', {
    url: '/:projectName',
    templateUrl: 'app/components/mapping/partials/project.html',
    controller: 'ProjectCtrl as proj',
    authenticate: true
})

And while MapCtrl keeps working correctly, ProjectCtrl still doesn't.

2
  • try controller: 'MapCtrl',controllerAs:'map' instead of controller: 'MapCtrl as map' Commented Oct 12, 2015 at 8:55
  • MapCtrl is working fine, its ProjectCtrl which never loads. Commented Oct 12, 2015 at 8:55

2 Answers 2

1

Found the issue... There were two instances of ProjectCtrl in this project:

enter image description here

Apparently, this causes some sort of silent conflict because there was absolutely no console error. Since the second instance was also linked on index.html, after the one that I wanted to load, it was probably simply replacing the correct version. Debugging nightmare.

Fixed now.

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

2 Comments

Good you made it! Enjoy mighty UI-Router
Thank you again for your tremendous help and sorry to inconvenience you three times with the same problem. Maybe it won't even be the last...
0

An abstract state cannot exist by definition so having a template URL for the parent and the children (which won't inherit the parent's templateUrl because the children define their own) is highly dubious IMO.

Im also wondering if there is trouble distinguising between ... url: '' AND url: '/:projectName'

(Although it should handle the distinction). However, to make sure I suggest a step-by-step approach. Kick off with the following mapping I suggest and then enhance it from there ...

.state('mapping', {
    abstract: true,
    authenticate: true
})
.state('mapping.all', {
    url: '/',
    templateUrl: 'app/components/mapping/partials/all.html',
    controller: 'MapCtrl as map',
})
.state('mapping.project', {
    url: '/project/:projectName',
    templateUrl: 'app/components/mapping/partials/project.html',
    controller: 'ProjectCtrl as proj',
})

4 Comments

I do believe the abstract state still needs url though, am I wrong?
Anything defined in the abstract state (such as URL) simply enables the children to inherit that property - e.g. if they dont define their own URL they get their URL from the parent. Since they define their own URL there is no point defining the URL in the abstract state
I understand, but the templateUrl does make sense to include at least a ui-view, correct?
No because the state cannot exist, thus it cannot be viewed and thus it does not need a template URL for the ui-view ... The only time I would ever use a template URL in an abstract state is if I wanted to have 2 different URLs (defined in 2 child states) that both shared the same view

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.