TJB
TJB

Reputation: 3846

Angular $stateProvider hits two states

In being given the task of converting an old Flask web application into Django, I was introduced to the world of Angular. I am still very new, and am having troubles with Angular's ui-routerJs. It is my understanding that given the Angular module below, $urlRouterProvider will go through each $stateProvider state, and look for a matching url. If there is none, $urlRouterProvider.otherwise will supply the url that is provided as one of its argument. when I go to localhost:8000/home/, the root location where app.guest triggers, it seems to hit two states, the 'auth' state, and the 'auth.login' state because it is loading both static/templates/home/partials/auth/main.html, and 'static/templates/home/partials/auth/login.html'. Furthermore, since the first state does not supply a url, shouldn't that be what it hits first ?

/** ngInject */
    function Config($locationProvider, $stateProvider, $urlRouterProvider) {
    $locationProvider.html5Mode(true);

    $urlRouterProvider.otherwise('/login');

    $stateProvider
        .state('auth', {
            abstract: true,
            templateUrl: 'static/templates/home/partials/auth/main.html',
            controller: 'Auth',
            controllerAs: 'auth'
        })
        .state('auth.login', {
            url: '/login?next',
            templateUrl: 'static/templates/home/partials/auth/login.html',
            controller: 'Login',
            controllerAs: 'vm'
        })
        .state('auth.reset', {
            url: '/reset',
            template: "<div class='card card-half'>This screen is not yet ready. ¯\\_(ツ)_/¯</div>",
            controller: broadcastReady
        })
        .state('auth.join', {
            abstract: true,
            templateUrl: '/static/templates/home/partials/auth/join.html',
            controller: 'Join',
            controllerAs: 'vm'
        })
        .state('auth.join.personal', {
            url: '/join?invite',
            templateUrl: '/static/templates/home/partials/auth/join.personal.html',
            controller: broadcastReady
        })
        .state('auth.join.team', {
            templateUrl: '/static/templates/home/partials/auth/join.team.html',
            controller: broadcastReady
        })
        .state('auth.accept', {
            url: '/accept/{token}?data',
            views: {
                '': {
                    templateUrl: '/views/home/partials/auth/accept.html',
                    controller: 'Accept',
                    controllerAs: 'vm',
                    reloadOnSearch: false
                },
                '[email protected]': {
                    templateUrl: '/views/home/partials/auth/accept.signup.html'
                },
                '[email protected]': {
                    templateUrl: '/views/home/partials/auth/accept.login.html'
                }
            }
        });

site.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="shortcut icon" href="/images/favicons/favicon.ico">
  <link rel="icon" sizes="16x16 32x32 64x64" href="/images/favicons/favicon.ico">
  <link rel="icon" type="image/png" sizes="196x196"
        href="/images/favicons/favicon-192.png">
  <link rel="icon" type="image/png" sizes="160x160"
        href="/images/favicons/favicon-160.png">
  <link rel="icon" type="image/png" sizes="96x96" href="/images/favicons/favicon-96.png">
  <link rel="icon" type="image/png" sizes="64x64" href="/images/favicons/favicon-64.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicons/favicon-32.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicons/favicon-16.png">
  <link rel="apple-touch-icon" href="/images/favicons/favicon-57.png">
  <link rel="apple-touch-icon" sizes="114x114" href="/images/favicons/favicon-114.png">
  <link rel="apple-touch-icon" sizes="72x72" href="/images/favicons/favicon-72.png">
  <link rel="apple-touch-icon" sizes="144x144" href="/images/favicons/favicon-144.png">
  <link rel="apple-touch-icon" sizes="60x60" href="/images/favicons/favicon-60.png">
  <link rel="apple-touch-icon" sizes="120x120" href="/images/favicons/favicon-120.png">
  <link rel="apple-touch-icon" sizes="76x76" href="/images/favicons/favicon-76.png">
  <link rel="apple-touch-icon" sizes="152x152" href="/images/favicons/favicon-152.png">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/favicons/favicon-180.png">
  <link rel="stylesheet/less" href="../webapp/static/less/accounts/all.less">
  <meta name="msapplication-TileColor" content="#FFFFFF">
  <meta name="msapplication-TileImage" content="/images/favicons/favicon-144.png">
  <meta name="msapplication-config" content="/images/favicons/browserconfig.xml">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.js"></script>
    <script src="https://code.angularjs.org/1.4.5/angular-animate.js"></script>
    <script src="https://code.angularjs.org/1.4.5/angular-messages.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.3.1/ui-bootstrap.js"></script>

  <!--[% assets "css_all" -%]-->
    <!--<link rel="stylesheet" href="[= ASSET_URL =]" />-->
  <!--[%- endassets %]-->

  {% block head %} {% endblock %}
  {% block styles %} {% endblock %}
  <script type="text/javascript">
    window.HL = {};
//    window.HL.userdata = {= userdata | tojson | safe =};
  </script>
</head>

<body class="{% block layout %}{% endblock %}" ng-app={% block ngapp %}{% endblock %}>

{% block nav %}
{% include "nav.html" %}
{% endblock %}

{% include "site-alert.html" %}

<div class="{% block container %}container container-main{% endblock %}">
  {% block content_wrapper %}
      {% block content %}
      {% endblock %}
  {% endblock %}
</div>

{% block footer %}
{% include "footer.html" %}
{% endblock %}

<!--[% assets "js_vendor" -%]-->
<!--<script src="[= ASSET_URL =]"></script>-->
<!--[%- endassets  %]-->

<!--[% assets "js_templates" -%]-->
<!--<script src="[= ASSET_URL =]"></script>-->
<!--[%- endassets %]-->

<!--[% assets "js_app" -%]-->
<!--<script src="[= ASSET_URL =]"></script>-->
<!--[%- endassets %]-->

{% block scripts %} {% endblock %}
</body>
</html>

'static/templates/home/partials/auth/main.html'

<div ui-view ng-show="auth.viewReady"></div>

<div class="card" ng-hide="auth.viewReady">
  <h4>Hope you&rsquo;re having a great day!</h4>
  <p>
    <i class="fa fa-circle-o-notch fa-spin"></i>
    Please wait&hellip;
  </p>
</div>

home.index.html

{% extends "site.html" %}
{% load staticfiles %}

{% block scripts %}
    <script type="text/javascript" src="{% static "js/humanlink.js" %}"></script>
{% endblock %}

{% block title %} Humanlink Home {% endblock %}

{% block ngapp %}"app.guest"{% endblock %}

{% block head %}
<base href="/home/">
{% endblock %}

{% block content %}
<div>
   <div ui-view>
       <i>CONTENT WILL GO HERE</i>
   </div>
</div>
<br>
{% endblock %}

'static/templates/home/partials/auth/login.html'

<div class="account-login" id="login-view">
  <div class="card card-half">
    <h2 class="text-center">Welcome back!</h2>
    <h4 class="text-center">Sign in to your account.</h4>

    <div class="alert alert-danger" ng-if="vm.errorMessage">
      {{ vm.errorMessage }}
    </div>

    <form class="form-horizontal" name="form" ng-submit="vm.login(vm.auth)">

      <div class="form-group">
        <label for="email" class="col-sm-3 control-label">Email</label>

        <div class="col-sm-9 col-md-7">
          <input type="email" id="email"
              class="form-control"
              placeholder="[email protected]"
              ng-model="vm.auth.email"
              required
              hl-focus>
        </div>
      </div>

      <div class="form-group">
        <label for="password" class="col-sm-3 control-label">Password</label>

        <div class="col-sm-9 col-md-7">
          <input type="password" id="password" name="password"
              class="form-control"
              placeholder="******"
              ng-model="vm.auth.password"
              required minlength="6">

          <div class="has-warning" ng-if="form.password.$dirty">
            <div class="help-block" ng-messages="form.password.$error">
              <div ng-message="minlength">Please enter at least six characters.
              </div>
            </div>
          </div>

        </div>
      </div>

      <div class="form-group">
        <div class="col-sm-3"></div>
        <div class="col-sm-9 col-md-7">
          <button type="submit" class="btn btn-block btn-secondary"
              ng-disabled="!form.$valid || vm.submitBusy">
            Sign in
            <span ng-if="vm.submitBusy"><i class="fa fa-circle-o-notch fa-spin"></i></span>
          </button>
        </div>
      </div>

    </form>

  </div>
</div>

<div class="col-sm-6 col-sm-offset-3">
  <p>Forgot your password? Reset it
      <a ui-sref="auth.reset">here</a>.</p>
  <p>Trying to create a team?
      <a ui-sref="auth.join.personal">Sign up</a> to get started.</p>
</div>

enter image description here

Upvotes: 0

Views: 105

Answers (1)

rabruce
rabruce

Reputation: 133

Auth is an abstract state, so it is not loaded directly. Instead it is a 'parent' state, in which the substates are loaded into.

Think of it like this:

Auth

  • login
  • reset

The login and reset states load into the auth abstract view. Since the templateUrl is set on the abstract view, the templates for login and reset load into the ui-view set on the abstract view, which is main.html.

As far as your URL loading goes, it hits the login state because the url /home is not set, so the following line triggers.

$urlRouterProvider.otherwise('/login');

Upvotes: 1

Related Questions