angular-ui / ui-router

The de-facto solution to flexible routing with nested views in AngularJS
http://ui-router.github.io/
MIT License
13.56k stars 3.01k forks source link

$transition$.params() includes a "#" key #3744

Closed tandrewnichols closed 4 years ago

tandrewnichols commented 5 years ago

I'm trying to transition from $stateParams to $transition$.params() in an Angular.js (current at 1.4) app. Things are mostly working except that I'm seeing an extra key in all my params.

Here's a relevant snippet from my router:

// app/admin/admin-router.js (lines 2-25)
$uiViewScrollProvider.useAnchorScroll();
$urlMatcherFactoryProvider.strictMode(false);

$urlRouterProvider.otherwise('member');

// Base admin area
$stateProvider.state('admin', {
  url: '/',
  templateUrl: 'admin/index.html',
  controller: 'AdminController'
});

// Member search etc.
$stateProvider.state('admin.member', {
  url: 'member',
  templateUrl: 'admin/member/search.html',
  controller: 'MemberSearchController'
})
.state('admin.member.results', {
  url: '/results?subId&email&slug&phone&firstname&lastname&partialEmail&role',
  templateUrl: 'admin/member/search-results.html',
  controller: 'MemberSearchResultsController'
})

In the MemberSearchResultsController, the parameters are populated by a search form. If I fill one field in and log params inside the controller I get this:

{
  #: null,
  subId: 'banana',
  email: undefined,
  phone: undefined,
  firstname: undefined,
  lastname: undefined,
  partialEmail: undefined,
  role: undefined
}

which is a problem because I'm currently blindly serializing that to send to a remote API and null is not dropped the way undefined is, so I end up with something like http://mydomain.com/myroute?%23=null&subId=banana. Obviously, I can work around this case, but everywhere I've checked params, they always include this extraneous "#" key. Why is that? Is this something legacy about my app or an issue with ui-router? FWIW, if I log $transition$.targetState().params() the # key is not present.

I'm also setting

  $locationProvider.html5Mode(false);
  $locationProvider.hashPrefix('!');

in a different config block in case that's relevant (and I suspect that it is).

This is a (check one box):

My version of UI-Router is: (type version)

1.0.17

Bug Report

Current Behavior:

I get an extra key in my params: "#"

Expected Behavior:

I get only the params I specify in my routing config.

soelinn commented 5 years ago

Description

When using AngularJS version 1.5.11, it works fine.
Starting with version >= 1.6.x, the same code breaks.

How To Test

(1) npm install -g live-server from https://www.npmjs.com/package/live-server
(2) live-server --port=4200 ./
(3) go to http://127.0.0.1:4200/#/?id=1234

Current Behavior

Using AngularJS version >= 1.6, navigating to http://127.0.0.1:4200/#/?id=1234,
@uirouter/angularjs gets stuck on http://127.0.0.1:4200/#!#%2F%3Fid=1234.

Expected Behavior

Using AngularJS version <= 1.5.11, navigating to http://127.0.0.1:4200/#/?id=1234,
@uirouter/angularjs routes to http://127.0.0.1:4200/#/foobar?id=1234 successfully.

Source Code

GitHub keeps failing to save the comment. Here is the Plunker link for this.
https://plnkr.co/edit/VH0Xme?p=info

<!DOCTYPE html>
<html data-ng-app="myApp" ng-strict-di ng-controller="AppController">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>UI-Router Bug Report</title>
  </head>
  <body>
    <ui-view></ui-view>
    <!-- DOES NOT WORK -->
    <!-- <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.10/angular.min.js"></script> -->

    <!-- WORKS -->
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.11/angular.min.js"></script>
    <script src="https://unpkg.com/@uirouter/angularjs@1.0.20/release/angular-ui-router.min.js"></script>
    <script type="text/javascript">
      angular
        .module("myApp", ["ui.router"])
        .config([
          "$stateProvider",
          "$urlRouterProvider",
          function($stateProvider, $urlRouterProvider) {
            $stateProvider
              .state("index", {
                url: "",
                controller: "AppController",
                template: "<h1>ERROR</h1><h2>Stuck on AppController</h2>"
              })
              .state("foobar", {
                url: "/foobar?id&otherId",
                controller: "FooBarController",
                template:
                  "<h1>SUCCESS</h1><h2>UI-View renders FooBarController.</h2>"
              });
            $urlRouterProvider.otherwise(function($injector, $location) {
              var $state = $injector.get("$state");
              $state.go("foobar", $location.search());
              return $location.path();
            });
          }
        ])
        .controller("AppController", ["$state", "$stateParams", AppController])
        .controller("FooBarController", [
          "$state",
          "$stateParams",
          FooBarController
        ]);

      function AppController($state, $stateParams) {
        console.info("[INFO] AppController -- $stateParams", $stateParams);
      }
      function FooBarController($state, $stateParams) {
        console.info("[INFO] FooBarController -- $stateParams", $stateParams);
      }
    </script>
  </body>
</html>
tandrewnichols commented 5 years ago

That doesn't seem related to the issue I posted.

soelinn commented 5 years ago

You are right that it is not directly related to your reported issue. However, I am convinced that the issues we are reporting are indirectly related due to the AngularJS version used.

I also noticed the $stateParams["#"] value in the $stateParams injected into the Angular Controller as you reported depending on the AngularJS version used.

I posted my code because it is easier for the ui-router maintainers to test.

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

This does not mean that the issue is invalid. Valid issues may be reopened.

Thank you for your contributions.