Adding :id to guarded component path causes infinite loop?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















This stackblitz demo should not render because of the :id path variable in the route to the guarded HelloComponent.



{ path: ':id', component: HelloComponent, canActivate: [AuthGuard] },
{ path: '', component: CollectionPageComponent, canActivate: [AuthGuard] }];


If :id is removed, then the login view renders, since both paths will be guarded, but if the :id variable is added back to the path, the demo spins forever.



Is this a bug or am I violating some router principle by adding :id to this location?



Note that I replaced the ViewBook component with a HelloComponent just for trouble shooting purposes. The books module is lazy and the way that this is supposed to work is that if the user authenticates and selects a book in search the book can be shown with the path books/4545342, which would trigger the :id path, but if just books is requested, without a path parameter then the book collection is shown.



I'm using this demo as a reference point. Is uses a essentially the same routing configuration.



I tried flipping the path parameters here. It seems in older versions of Angular the order does not matter, but now it does.



Filed a bug report here










share|improve this question































    0















    This stackblitz demo should not render because of the :id path variable in the route to the guarded HelloComponent.



    { path: ':id', component: HelloComponent, canActivate: [AuthGuard] },
    { path: '', component: CollectionPageComponent, canActivate: [AuthGuard] }];


    If :id is removed, then the login view renders, since both paths will be guarded, but if the :id variable is added back to the path, the demo spins forever.



    Is this a bug or am I violating some router principle by adding :id to this location?



    Note that I replaced the ViewBook component with a HelloComponent just for trouble shooting purposes. The books module is lazy and the way that this is supposed to work is that if the user authenticates and selects a book in search the book can be shown with the path books/4545342, which would trigger the :id path, but if just books is requested, without a path parameter then the book collection is shown.



    I'm using this demo as a reference point. Is uses a essentially the same routing configuration.



    I tried flipping the path parameters here. It seems in older versions of Angular the order does not matter, but now it does.



    Filed a bug report here










    share|improve this question



























      0












      0








      0








      This stackblitz demo should not render because of the :id path variable in the route to the guarded HelloComponent.



      { path: ':id', component: HelloComponent, canActivate: [AuthGuard] },
      { path: '', component: CollectionPageComponent, canActivate: [AuthGuard] }];


      If :id is removed, then the login view renders, since both paths will be guarded, but if the :id variable is added back to the path, the demo spins forever.



      Is this a bug or am I violating some router principle by adding :id to this location?



      Note that I replaced the ViewBook component with a HelloComponent just for trouble shooting purposes. The books module is lazy and the way that this is supposed to work is that if the user authenticates and selects a book in search the book can be shown with the path books/4545342, which would trigger the :id path, but if just books is requested, without a path parameter then the book collection is shown.



      I'm using this demo as a reference point. Is uses a essentially the same routing configuration.



      I tried flipping the path parameters here. It seems in older versions of Angular the order does not matter, but now it does.



      Filed a bug report here










      share|improve this question
















      This stackblitz demo should not render because of the :id path variable in the route to the guarded HelloComponent.



      { path: ':id', component: HelloComponent, canActivate: [AuthGuard] },
      { path: '', component: CollectionPageComponent, canActivate: [AuthGuard] }];


      If :id is removed, then the login view renders, since both paths will be guarded, but if the :id variable is added back to the path, the demo spins forever.



      Is this a bug or am I violating some router principle by adding :id to this location?



      Note that I replaced the ViewBook component with a HelloComponent just for trouble shooting purposes. The books module is lazy and the way that this is supposed to work is that if the user authenticates and selects a book in search the book can be shown with the path books/4545342, which would trigger the :id path, but if just books is requested, without a path parameter then the book collection is shown.



      I'm using this demo as a reference point. Is uses a essentially the same routing configuration.



      I tried flipping the path parameters here. It seems in older versions of Angular the order does not matter, but now it does.



      Filed a bug report here







      javascript angular typescript






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 4 at 0:15







      Ole

















      asked Jan 3 at 22:34









      OleOle

      1




      1
























          2 Answers
          2






          active

          oldest

          votes


















          1














          When using the router, you have to be careful where you import modules. Ideally, you won't import a lazy loaded module in your application anywhere.



          In your case, you're importing the book module into your app module. This adds the routes to the router config at the root level. The router does fancy unknown-to-me things with lazy loaded modules. Routes that cannot be activated won't be added to the config.



          See new config after removing book module from app module:



          0: {path: "login", component: ƒ}
          1: {path: "", redirectTo: "books", pathMatch: "full"}
          2: {path: "books", loadChildren: ƒ, _loadedConfig: LoadedRouterConfig}
          3: {path: "**", component: ƒ}


          VS before the move:



          0: {path: ":id", component: ƒ}
          1: {path: "", component: ƒ}
          2: {path: "login", component: ƒ}
          3: {path: "", redirectTo: "books", pathMatch: "full"}
          4: {path: "books", loadChildren: ƒ, _loadedConfig: LoadedRouterConfig}
          5: {path: "**", component: ƒ}


          To fix: simply don't import your book module in the app module. In your case, you'll need to import the HttpClientModule in your book module.






          share|improve this answer
























          • Good catch!! Thank you so much for pointing that out!

            – Ole
            Jan 19 at 1:57











          • Created another Feature Request per you answer: github.com/angular/angular/issues/28248

            – Ole
            Jan 19 at 3:45











          • That's a good idea! It'll be interesting to see what they say as I am not familiar enough with the multi providers and/or how to detect if the provider already exists.

            – OneLunch Man
            Jan 19 at 3:58



















          0














          Try this, pay attention I change the order, and added pathMatch to '' route,



          { path: '', component: CollectionPageComponent, pathMatch: 'full', canActivate: [AuthGuard] },
          { path: ':id', component: HelloComponent, canActivate: [AuthGuard] },



          • if the issue is not solved let me know to delete my answer






          share|improve this answer
























          • IIUC the more specific paths are supposed to be first. So for example if we added find then that would come before :id. In this case the empty '' is being triggered first, and now the :id path will never fire. Reviewers let me know if I'm wrong about this and I can accept the answer. Its an attempt at refactoring this demo: stackblitz.com/edit/… In it the :id path comes before the '' path.

            – Ole
            Jan 3 at 22:52











          • Also this is what the documentation says: The order of the routes in the configuration matters and this is by design. The router uses a first-match wins strategy when matching routes, so more specific routes should be placed above less specific routes.

            – Ole
            Jan 3 at 22:58











          • angular.io/guide/router

            – Ole
            Jan 3 at 22:58











          • I added a link to the demo routing that works in the question. I think some of the core semantics of angular have been refactored since the demo was published, because canActivate can no longer be added in conjunction with loadChildren for example.

            – Ole
            Jan 3 at 23:12











          • In an older version of angular, it seems the order does not matter: stackblitz.com/edit/…

            – Ole
            Jan 4 at 0:15












          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54030737%2fadding-id-to-guarded-component-path-causes-infinite-loop%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          When using the router, you have to be careful where you import modules. Ideally, you won't import a lazy loaded module in your application anywhere.



          In your case, you're importing the book module into your app module. This adds the routes to the router config at the root level. The router does fancy unknown-to-me things with lazy loaded modules. Routes that cannot be activated won't be added to the config.



          See new config after removing book module from app module:



          0: {path: "login", component: ƒ}
          1: {path: "", redirectTo: "books", pathMatch: "full"}
          2: {path: "books", loadChildren: ƒ, _loadedConfig: LoadedRouterConfig}
          3: {path: "**", component: ƒ}


          VS before the move:



          0: {path: ":id", component: ƒ}
          1: {path: "", component: ƒ}
          2: {path: "login", component: ƒ}
          3: {path: "", redirectTo: "books", pathMatch: "full"}
          4: {path: "books", loadChildren: ƒ, _loadedConfig: LoadedRouterConfig}
          5: {path: "**", component: ƒ}


          To fix: simply don't import your book module in the app module. In your case, you'll need to import the HttpClientModule in your book module.






          share|improve this answer
























          • Good catch!! Thank you so much for pointing that out!

            – Ole
            Jan 19 at 1:57











          • Created another Feature Request per you answer: github.com/angular/angular/issues/28248

            – Ole
            Jan 19 at 3:45











          • That's a good idea! It'll be interesting to see what they say as I am not familiar enough with the multi providers and/or how to detect if the provider already exists.

            – OneLunch Man
            Jan 19 at 3:58
















          1














          When using the router, you have to be careful where you import modules. Ideally, you won't import a lazy loaded module in your application anywhere.



          In your case, you're importing the book module into your app module. This adds the routes to the router config at the root level. The router does fancy unknown-to-me things with lazy loaded modules. Routes that cannot be activated won't be added to the config.



          See new config after removing book module from app module:



          0: {path: "login", component: ƒ}
          1: {path: "", redirectTo: "books", pathMatch: "full"}
          2: {path: "books", loadChildren: ƒ, _loadedConfig: LoadedRouterConfig}
          3: {path: "**", component: ƒ}


          VS before the move:



          0: {path: ":id", component: ƒ}
          1: {path: "", component: ƒ}
          2: {path: "login", component: ƒ}
          3: {path: "", redirectTo: "books", pathMatch: "full"}
          4: {path: "books", loadChildren: ƒ, _loadedConfig: LoadedRouterConfig}
          5: {path: "**", component: ƒ}


          To fix: simply don't import your book module in the app module. In your case, you'll need to import the HttpClientModule in your book module.






          share|improve this answer
























          • Good catch!! Thank you so much for pointing that out!

            – Ole
            Jan 19 at 1:57











          • Created another Feature Request per you answer: github.com/angular/angular/issues/28248

            – Ole
            Jan 19 at 3:45











          • That's a good idea! It'll be interesting to see what they say as I am not familiar enough with the multi providers and/or how to detect if the provider already exists.

            – OneLunch Man
            Jan 19 at 3:58














          1












          1








          1







          When using the router, you have to be careful where you import modules. Ideally, you won't import a lazy loaded module in your application anywhere.



          In your case, you're importing the book module into your app module. This adds the routes to the router config at the root level. The router does fancy unknown-to-me things with lazy loaded modules. Routes that cannot be activated won't be added to the config.



          See new config after removing book module from app module:



          0: {path: "login", component: ƒ}
          1: {path: "", redirectTo: "books", pathMatch: "full"}
          2: {path: "books", loadChildren: ƒ, _loadedConfig: LoadedRouterConfig}
          3: {path: "**", component: ƒ}


          VS before the move:



          0: {path: ":id", component: ƒ}
          1: {path: "", component: ƒ}
          2: {path: "login", component: ƒ}
          3: {path: "", redirectTo: "books", pathMatch: "full"}
          4: {path: "books", loadChildren: ƒ, _loadedConfig: LoadedRouterConfig}
          5: {path: "**", component: ƒ}


          To fix: simply don't import your book module in the app module. In your case, you'll need to import the HttpClientModule in your book module.






          share|improve this answer













          When using the router, you have to be careful where you import modules. Ideally, you won't import a lazy loaded module in your application anywhere.



          In your case, you're importing the book module into your app module. This adds the routes to the router config at the root level. The router does fancy unknown-to-me things with lazy loaded modules. Routes that cannot be activated won't be added to the config.



          See new config after removing book module from app module:



          0: {path: "login", component: ƒ}
          1: {path: "", redirectTo: "books", pathMatch: "full"}
          2: {path: "books", loadChildren: ƒ, _loadedConfig: LoadedRouterConfig}
          3: {path: "**", component: ƒ}


          VS before the move:



          0: {path: ":id", component: ƒ}
          1: {path: "", component: ƒ}
          2: {path: "login", component: ƒ}
          3: {path: "", redirectTo: "books", pathMatch: "full"}
          4: {path: "books", loadChildren: ƒ, _loadedConfig: LoadedRouterConfig}
          5: {path: "**", component: ƒ}


          To fix: simply don't import your book module in the app module. In your case, you'll need to import the HttpClientModule in your book module.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 18 at 20:31









          OneLunch ManOneLunch Man

          1,893820




          1,893820













          • Good catch!! Thank you so much for pointing that out!

            – Ole
            Jan 19 at 1:57











          • Created another Feature Request per you answer: github.com/angular/angular/issues/28248

            – Ole
            Jan 19 at 3:45











          • That's a good idea! It'll be interesting to see what they say as I am not familiar enough with the multi providers and/or how to detect if the provider already exists.

            – OneLunch Man
            Jan 19 at 3:58



















          • Good catch!! Thank you so much for pointing that out!

            – Ole
            Jan 19 at 1:57











          • Created another Feature Request per you answer: github.com/angular/angular/issues/28248

            – Ole
            Jan 19 at 3:45











          • That's a good idea! It'll be interesting to see what they say as I am not familiar enough with the multi providers and/or how to detect if the provider already exists.

            – OneLunch Man
            Jan 19 at 3:58

















          Good catch!! Thank you so much for pointing that out!

          – Ole
          Jan 19 at 1:57





          Good catch!! Thank you so much for pointing that out!

          – Ole
          Jan 19 at 1:57













          Created another Feature Request per you answer: github.com/angular/angular/issues/28248

          – Ole
          Jan 19 at 3:45





          Created another Feature Request per you answer: github.com/angular/angular/issues/28248

          – Ole
          Jan 19 at 3:45













          That's a good idea! It'll be interesting to see what they say as I am not familiar enough with the multi providers and/or how to detect if the provider already exists.

          – OneLunch Man
          Jan 19 at 3:58





          That's a good idea! It'll be interesting to see what they say as I am not familiar enough with the multi providers and/or how to detect if the provider already exists.

          – OneLunch Man
          Jan 19 at 3:58













          0














          Try this, pay attention I change the order, and added pathMatch to '' route,



          { path: '', component: CollectionPageComponent, pathMatch: 'full', canActivate: [AuthGuard] },
          { path: ':id', component: HelloComponent, canActivate: [AuthGuard] },



          • if the issue is not solved let me know to delete my answer






          share|improve this answer
























          • IIUC the more specific paths are supposed to be first. So for example if we added find then that would come before :id. In this case the empty '' is being triggered first, and now the :id path will never fire. Reviewers let me know if I'm wrong about this and I can accept the answer. Its an attempt at refactoring this demo: stackblitz.com/edit/… In it the :id path comes before the '' path.

            – Ole
            Jan 3 at 22:52











          • Also this is what the documentation says: The order of the routes in the configuration matters and this is by design. The router uses a first-match wins strategy when matching routes, so more specific routes should be placed above less specific routes.

            – Ole
            Jan 3 at 22:58











          • angular.io/guide/router

            – Ole
            Jan 3 at 22:58











          • I added a link to the demo routing that works in the question. I think some of the core semantics of angular have been refactored since the demo was published, because canActivate can no longer be added in conjunction with loadChildren for example.

            – Ole
            Jan 3 at 23:12











          • In an older version of angular, it seems the order does not matter: stackblitz.com/edit/…

            – Ole
            Jan 4 at 0:15
















          0














          Try this, pay attention I change the order, and added pathMatch to '' route,



          { path: '', component: CollectionPageComponent, pathMatch: 'full', canActivate: [AuthGuard] },
          { path: ':id', component: HelloComponent, canActivate: [AuthGuard] },



          • if the issue is not solved let me know to delete my answer






          share|improve this answer
























          • IIUC the more specific paths are supposed to be first. So for example if we added find then that would come before :id. In this case the empty '' is being triggered first, and now the :id path will never fire. Reviewers let me know if I'm wrong about this and I can accept the answer. Its an attempt at refactoring this demo: stackblitz.com/edit/… In it the :id path comes before the '' path.

            – Ole
            Jan 3 at 22:52











          • Also this is what the documentation says: The order of the routes in the configuration matters and this is by design. The router uses a first-match wins strategy when matching routes, so more specific routes should be placed above less specific routes.

            – Ole
            Jan 3 at 22:58











          • angular.io/guide/router

            – Ole
            Jan 3 at 22:58











          • I added a link to the demo routing that works in the question. I think some of the core semantics of angular have been refactored since the demo was published, because canActivate can no longer be added in conjunction with loadChildren for example.

            – Ole
            Jan 3 at 23:12











          • In an older version of angular, it seems the order does not matter: stackblitz.com/edit/…

            – Ole
            Jan 4 at 0:15














          0












          0








          0







          Try this, pay attention I change the order, and added pathMatch to '' route,



          { path: '', component: CollectionPageComponent, pathMatch: 'full', canActivate: [AuthGuard] },
          { path: ':id', component: HelloComponent, canActivate: [AuthGuard] },



          • if the issue is not solved let me know to delete my answer






          share|improve this answer













          Try this, pay attention I change the order, and added pathMatch to '' route,



          { path: '', component: CollectionPageComponent, pathMatch: 'full', canActivate: [AuthGuard] },
          { path: ':id', component: HelloComponent, canActivate: [AuthGuard] },



          • if the issue is not solved let me know to delete my answer







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 3 at 22:45









          RezaRahmatiRezaRahmati

          7,72623280




          7,72623280













          • IIUC the more specific paths are supposed to be first. So for example if we added find then that would come before :id. In this case the empty '' is being triggered first, and now the :id path will never fire. Reviewers let me know if I'm wrong about this and I can accept the answer. Its an attempt at refactoring this demo: stackblitz.com/edit/… In it the :id path comes before the '' path.

            – Ole
            Jan 3 at 22:52











          • Also this is what the documentation says: The order of the routes in the configuration matters and this is by design. The router uses a first-match wins strategy when matching routes, so more specific routes should be placed above less specific routes.

            – Ole
            Jan 3 at 22:58











          • angular.io/guide/router

            – Ole
            Jan 3 at 22:58











          • I added a link to the demo routing that works in the question. I think some of the core semantics of angular have been refactored since the demo was published, because canActivate can no longer be added in conjunction with loadChildren for example.

            – Ole
            Jan 3 at 23:12











          • In an older version of angular, it seems the order does not matter: stackblitz.com/edit/…

            – Ole
            Jan 4 at 0:15



















          • IIUC the more specific paths are supposed to be first. So for example if we added find then that would come before :id. In this case the empty '' is being triggered first, and now the :id path will never fire. Reviewers let me know if I'm wrong about this and I can accept the answer. Its an attempt at refactoring this demo: stackblitz.com/edit/… In it the :id path comes before the '' path.

            – Ole
            Jan 3 at 22:52











          • Also this is what the documentation says: The order of the routes in the configuration matters and this is by design. The router uses a first-match wins strategy when matching routes, so more specific routes should be placed above less specific routes.

            – Ole
            Jan 3 at 22:58











          • angular.io/guide/router

            – Ole
            Jan 3 at 22:58











          • I added a link to the demo routing that works in the question. I think some of the core semantics of angular have been refactored since the demo was published, because canActivate can no longer be added in conjunction with loadChildren for example.

            – Ole
            Jan 3 at 23:12











          • In an older version of angular, it seems the order does not matter: stackblitz.com/edit/…

            – Ole
            Jan 4 at 0:15

















          IIUC the more specific paths are supposed to be first. So for example if we added find then that would come before :id. In this case the empty '' is being triggered first, and now the :id path will never fire. Reviewers let me know if I'm wrong about this and I can accept the answer. Its an attempt at refactoring this demo: stackblitz.com/edit/… In it the :id path comes before the '' path.

          – Ole
          Jan 3 at 22:52





          IIUC the more specific paths are supposed to be first. So for example if we added find then that would come before :id. In this case the empty '' is being triggered first, and now the :id path will never fire. Reviewers let me know if I'm wrong about this and I can accept the answer. Its an attempt at refactoring this demo: stackblitz.com/edit/… In it the :id path comes before the '' path.

          – Ole
          Jan 3 at 22:52













          Also this is what the documentation says: The order of the routes in the configuration matters and this is by design. The router uses a first-match wins strategy when matching routes, so more specific routes should be placed above less specific routes.

          – Ole
          Jan 3 at 22:58





          Also this is what the documentation says: The order of the routes in the configuration matters and this is by design. The router uses a first-match wins strategy when matching routes, so more specific routes should be placed above less specific routes.

          – Ole
          Jan 3 at 22:58













          angular.io/guide/router

          – Ole
          Jan 3 at 22:58





          angular.io/guide/router

          – Ole
          Jan 3 at 22:58













          I added a link to the demo routing that works in the question. I think some of the core semantics of angular have been refactored since the demo was published, because canActivate can no longer be added in conjunction with loadChildren for example.

          – Ole
          Jan 3 at 23:12





          I added a link to the demo routing that works in the question. I think some of the core semantics of angular have been refactored since the demo was published, because canActivate can no longer be added in conjunction with loadChildren for example.

          – Ole
          Jan 3 at 23:12













          In an older version of angular, it seems the order does not matter: stackblitz.com/edit/…

          – Ole
          Jan 4 at 0:15





          In an older version of angular, it seems the order does not matter: stackblitz.com/edit/…

          – Ole
          Jan 4 at 0:15


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54030737%2fadding-id-to-guarded-component-path-causes-infinite-loop%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Monofisismo

          Angular Downloading a file using contenturl with Basic Authentication

          Olmecas