John McArthur
John McArthur

Reputation: 1024

AngularJS ui-Router Nested Views throwing error: No Such State

I'm trying to set up a fairly complex page design with multiple ui-views. I've extracted it to a plunker (http://plnkr.co/edit/DwridY).

I have a main ui-view with several possible templates being loaded. Several of these templates have multiple ui-views of their own, for example:

<h1>Workflows</h1>
<div class="well">
    <div ui-view="workflow.list"></div>
 </div>
 <div class="well">
    <div ui-view="workflow.details"></div>
 </div>

The angular config lists the states like this:

  .state('tasks', {
    url: "/tasks",
    views: {
      "mainView": {
        templateUrl: "tasks.html",
        controller: "TaskController"
      }
    }
  })      
  .state("task.list", {
    url: "/taskList",
    views: {
      "task.list": {templateUrl: "task.list.html"},
    }
  })  
  .state("workflow", {
    url: "/workflows",
    views: {
      "mainView": {
        templateUrl: "workflow.html",
        controller: "WorkflowController"
      }
    }
  })
  .state("workflow.list", {
    url: "/workflowsList",
    views: {
      "workflow.list": {templateUrl: "workflow.list.html"},
      "workflow.details": {templateUrl: "workflow.details.html"}
    }
  });

The problem is that it works with the workflow state and it's sub-views but not the task state.

When I call:

function TaskController($scope, $state) {
   $state.transitionTo("task.list");
}

I get thrown an error:

No such state 'task.list'.

Can anyone see where I'm going wrong?

Upvotes: 1

Views: 2093

Answers (1)

Radim K&#246;hler
Radim K&#246;hler

Reputation: 123861

In general - if there is a . (dot) in the state name - UI-Router expects that it means:

  • before last dot - parent name (parents if more dots)
  • after last dot - current state name

so, what we are experiencing above with "task.list" is either

  • missing state "task" or
  • declaration "tasks.list" (the parent will be existing "tasks" instead of "task")

Here is the updated and working plunker, where I decided to use tasks as parent:

.state('tasks', {
    url: "/tasks",
    views: {
      "mainView": {
        templateUrl: "tasks.html",
        controller: "TaskController"
      }
    }
})      
//.state("task.list", {
.state("tasks.list", { // here we inherit from "tasks" not "task"
    url: "/taskList",
    views: {
      "task.list": {templateUrl: "task.list.html"},
    }
})  

Upvotes: 2

Related Questions