Angular deep nested router interface

How can I set up nested views in Angular for the following routes?

/#/app/dashboard
/#/app/product/
/#/app/product/new

Here is my current route configuration:

$stateProvider
    .state('app',{
        url: '/app',
        templateUrl: 'views/app.html',
        resolve: loadSequence('modernizr','moment'),
        abstract: true
    })
    .state('app.dashboard', {
        url: '/dashboard',
        templateUrl: 'views/dashboard.html',
        title: 'Dashboard',
        ncyBreadcrumb: {
            label: 'Dashboard'
    }
    }).state('app.product', {
        url: '/product',
        templateUrl: "views/product.html",
        title: 'Buttons',
        resolve: loadSequence('ngTable', 'ngTableCtrl')

    }).state('app.product.new', {
        parent: 'app.product',
        url: '/new',
        templateUrl: "views/add_product.html",
        title: 'Buttons',
        resolve: loadSequence('ngTable', 'ngTableCtrl')
    })

I am facing an issue where navigating to /#/app/product/new redirects me back to /#/app/product. Any idea why this is happening and how nested views work in Angular?

Thank you!

Answer №1

The method you described above is effective. I have created a working plunker to demonstrate the functionality of this state flow:

$stateProvider
    .state('app',{
        url: '/app', 
        templateUrl: 'views/app.html',
        abstract: true
    })
    .state('app.dashboard', {
        url: '/dashboard',
        templateUrl: 'views/dashboard.html'
    }).state('app.product', {
        url: '/product',
        templateUrl: "views/product.html",
    }).state('app.product.new', {
        parent: 'app.product',
        url: '/new',
        templateUrl: "views/add_product.html",
    })

The provided links work correctly and navigate as expected:

<a href="#/app/dashboard">
<a href="#/app/product">
<a href="#/app/product/new">

To ensure that the link

<a href="#/app/product/new/">

navigates to its parent (as specified in the question), you need to set the default redirection like this:

$urlRouterProvider.otherwise('/app/product');

If you use the incorrect link format like

// check the trailing /
<a href="#/app/product/new/">
// this will work
<a href="#/app/product/new">

In conclusion, the concept works well. There is no inherent reason for navigating from #/app/product/new to #/app/product

You can test it here

EXTEND

This is the faulty plunker originally provided. I have fixed it here

The first change was made to index.html - cleaning up unnecessary elements

  1. Deleting incorrect elements
  2. Using the full version of angular to pinpoint the issue

index.html:

<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <link rel="stylesheet" href="style.css" />
    <script data-require="<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a2c3ccc5d7cec3d08cc8d1e2938c968c968cda">[email protected]</a>" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js" data-semver="1.4.6"></script>
    <script data-require="ui-router@*" src="//rawgit.com/angular-ui/ui-router/0.2.15/release/angular-ui-router.js"></script>
    <!--<script>-->
    <script src="app.js"></script> 
  </head> 

The main issue was found in the wrong module reference name 'ui-router' instead of 'ui.router'

app.js

// Incorrect
var app = angular.module('plunker', ['ui-router'])
// Correct
var app = angular.module('plunker', ['ui.router'])

Another crucial point mentioned in comments was to target <div ui-view>. This was added to the parent state 'app.product'.

This ensures that each state (including children) must be injected somewhere, typically its parent. Therefore, the parent state 'app.product' should contain the ui-view target for its child state 'app.product.new'.

For more insights on named views and absolute naming, refer to these discussions:

  • Angular UI Router - Nested States with multiple layouts
  • Angularjs ui-router not reaching child controller
  • Angular ui-router : Container view and Default view

You can find the improved version here

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Fading away backdrop images for the header

I've created a header class in my CSS with the following styling- header { background-image: url('../img/header-bg.jpg'); background-repeat: none; background-attachment: scroll; background-position: center center; .backg ...

Warning: Unhandled promise rejection - Type error encountered when trying to access property

While working on a simple login validation, I encountered an issue when deliberately inputting an incorrect email in the login post method via postman. UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'password' of null at C:&b ...

An error was encountered with Ajax and JSONP due to an unexpected token causing a SyntaxError

Currently attempting to retrieve information from the host at 000webhost The data is in JSONP format: { "categories": { "category": [ { "name": "Android", "parent": "Computer Science", "ID": "2323" }, { ...

Is it advisable for postcss plugins to list postcss as a peer dependency?

I'm trying to incorporate the PostCSS Sass Color Function into my project. Unfortunately, I encountered this error: PostCSS plugin error: Your current version of PostCSS is 6.0.22, while postcss-sass-color-functions requires 5.2.18. This discrepa ...

Retrieve the thousand separator for numbers using Angular in various languages

When using the English locale, numbers appear as follows: 111,111,222.00, with a comma as the thousand separator and a point as the decimal separator. In languages like German, the same number would be represented as 111.111.222,00, reversing the positions ...

Executing a function by clicking on an element with the `ng-click` directive within a Bootstrap modal

I'm working on an app that allows users to submit posts for review. When a user clicks the add post button, I have a Bootstrap modal pop up to confirm their choice. Within this modal, there is a "confirm" button that should trigger a function. Strang ...

Using AngularJS to filter an array using the $filter function

Looking for a more elegant way to achieve the following task: myList.forEach(function(element){ if (!['state1', 'state2'].contains(element.state)){ myFilteredList.push(element) } }) I was thinking of using $filter('fi ...

Prevent JavaScript Errors when performing a page postback

I am currently using the Telerik RAD Editor control in my ASP.NET 4.0 application, which is outside of any update panel. On the same page, I have multiple ModalPopUps and update panels to prevent unexpected full postbacks. The page contains PageMethods inv ...

Calculating the 2D transformation matrix between two triangles using JavaScript

Seeking to determine the 2D transformation matrix for converting one triangle into another. The coordinates of both triangles' points are known. Although I typically utilize Paper.js for manipulating matrices, this particular scenario is outside i ...

Binding textarea data in Angular is a powerful feature that allows

I am looking to display the content from a textarea on the page in real time, but I am struggling to get the line breaks to show up. Here is my current code snippet: app.component.html <div class="ui center aligned grid">{{Form.value.address}}< ...

Documenting React Native Components: Best Practices and Tips

How can I add comments to a React Component? import React, { useState } from 'react'; import { Text, TextInput, View } from 'react-native'; import PropTypes from "prop-types"; const PizzaTranslator = ({ pizzaEmoji = ' ...

Dynamic and operational icons accompany the AngularJS search input field

Currently, I am delving into the world of AngularJS and experimenting with a search box. Within this search box, I want to incorporate three icons: a magnifying glass, a cross, and a spinner. For the first scenario, I envision the magnifying glass appearin ...

Building an npm module locally: A step-by-step guide

Imagine I'm in the process of working on an application called MyApp and I want to create an NPM module for it, named MyModule. Currently, I can think of two approaches to developing it: Make changes -> save -> npm install /path/to/module in M ...

Creating a promise to write data to a file

When executing the function, it creates a series of files but fails to write data to them. Strangely, omitting Promise.all at the end and not resolving the function actually results in the data being written to the files. It's puzzling that no matter ...

Transform this color matching game into an image matching game using JavaScript and jQuery

I have a color matching game that I would like to enhance by matching background-images instead of just background-colors. However, I am facing difficulties in making this change. For instance, instead of matching the color red with the text "red," I wan ...

Organizing DIVs upon website initialization

My website features a layout with three columns: <div id="column1"></div> <div id="column2"></div> <div id="column3"></div> I currently have 3 divs on the webpage: <div id="1">aaa</div> <div id="2">b ...

The functionality of AngularJS routing is malfunctioning

I'm having trouble with implementing angularJS routing on my page. Initially, it was working fine but now the browser is not returning anything. Here's the code snippet: angular.module('myRoutingApp', ['ngRoute']) .conf ...

Update the URL and parse the data in a Backbone collection

For the purpose of development, I am looking to replace the collection with fake JSON results either from a JSON variable or a JSON file. However, I encountered an error when attempting to do so using url http://jsfiddle.net/qhoc/uZhM8/ GET http://fiddle ...

Ways to properly exit a function

What is the best way to pass the apiKey from the createUser function in User.ts to Test.ts in my specific scenario? User.ts interface User { url: string, name: string, } class User{ async createUser( user: User ):Promise<void> { le ...

Combining Turn.js with AJAX for an interactive web experience

I've been experimenting with turn.js and struggling to find an example of loading dynamic pages with content via ajax. While the page is loading, it's not displaying all the results. For a JSON result from the controller, click here. <div clas ...