5

I have a problem with second router outlet when it's created in lazy-loaded module.

I started with this example where auxiliary routes https://stackblitz.com/edit/angular-nested-auxiliary-routes-irixxy work correctly.

My app is a bit more complicated and I use lazy loaded modules. In the new module, I wanted to use a second router outlet to dynamically show components. But I found out there is a problem with auxiliary routes when they are added in another module than the app module.

To check if the problem is in my app's routing I've created an example https://stackblitz.com/edit/angular-nested-auxiliary-routes-bpuswu which is similar to the base example but with added lazy-loaded module where routing (primary and secondary) is configured. Problem is that links with the secondary outlet path are not working giving the error Cannot match any routes. URL Segment: 'level-0'. Created invalid links are like [...]/level-0/(level-1//outlet1:aux-1). The same problem was in my app project.

Anyone has a similar problem and know how to fix it? Is there something wrong with my routine? Or is it a bug in the router?

Muhammad Arslan
  • 380
  • 1
  • 4
  • 10
user3626048
  • 706
  • 4
  • 19
  • 52

3 Answers3

0

I think your links are not correct:

Try this: <a [routerLink]="['/level-0/level-1', { outlets: { outlet1: 'aux-1' } }]">L1-A1 |

And also there should be an primary and auxilary in templates:

   <router-outlet></router-outlet>
<router-outlet name="outlet1"></router-outlet>`
rekna
  • 5,313
  • 7
  • 45
  • 54
0

The Problem

I managed to isolate the problem to the line

 outlet2: 'aux-3'

If we check the link created for <a [routerLink]="['/level-0', { outlets: { primary: ['level-1', { outlets: { primary: ['level-2', { outlets: { primary: ['level-3'], outlet2: 'aux-3' } }] } }], outlet1: 'aux-1' } }]">L1-A1/L2/L3-A3</a> we see that it produces

/level-0/(level-1/(level-2/(level-3//outlet2:a/u/x/-/3))//outlet1:aux-1)

It seems that aux-3 is converted to a/u/x/-/3. which is definitely not expected. It looks like the letters have been split and joint with /.

Solution/ Workaround

As stated earlier it seems an array was expected in the router outlet, so a simple solution is to pass an array instead

 outlet2: ['aux-3']

<a [routerLink]="['/level-0', { outlets: { primary: ['level-1', { outlets: { primary: ['level-2', { outlets: { primary: ['level-3'], outlet2: ['aux-3'] } }] } }], outlet1: ['aux-1'] } }]">L1-A1/L2/L3-A3</a>

Now the correct link is produced and the routes work correctly

Is there somethink wrong with my routing?

Your routes are working correctly. But as you may have noticed there is some inconsistency in the way the links are produced. I tried a simple router-link in This Stackblitz and it produces the same link.

<a [routerLink]="['/', { outlets: { outlet1: ['ab'] } }]">Link 1|</a> <br />
<a [routerLink]="['/', { outlets: { outlet1: 'ab' } }]">Link 2</a>

Below is the result of implementing the above

Working stackblitz demo

Auxilliary routes on Lazy loaded modules

A simple explanation to the problem you are facing is highlighted in this question Named router outlet and lazy loaded modules with a link provided in this answer https://stackoverflow.com/a/49367379/13680115 i.e auxilliary routes are not supported out of the box

Lazy load auxilary #10981

In the above post, In this comment the user highlights below

It seems that lazy load and auxiliary routes are not widely used together. We can see a lot of demos, separated but that's it. It's like no one uses it in a medium/large app

In the same post there seems to be a workaround here

We create a nested route with a componentless parent route. I have implemented that in the demo below and it works for the 1st level lazy loaded module. For the next level the routes are properly matched with no errors but unfortunately the component is not loaded, I believe a solution is to simply move the one level to the parent component. This way, one level of the auxilliary routes is loaded in the parent module while the other in the lazy loaded module

Demo Stackblitz

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Owen Kelvin
  • 14,054
  • 10
  • 41
  • 74
  • you focused on primary example project without module but my problem is that routing that was working in primary example (links "L1-A1" and "L1-A2" with outlet1) stopped working after moving routing to new module which I showed in second example. Can you check it? – user3626048 May 14 '21 at 07:53
  • Can you have a look at the updated solution – Owen Kelvin May 14 '21 at 09:46
  • I've checked your demo but it still doesn't work, maybe you forgot to save something on stackblitz? Also tried to copy your links provided above but it didn't work either. But after I moved router "outlet1" to Level1Component it started to work (with your links). I've created this example https://stackblitz.com/edit/angular-nested-auxiliary-routes-khaywj The only thing I couldn't do is link with outlet1 and outlet2 in one link, any idea how to do that? – user3626048 May 17 '21 at 18:49
  • You can check my updated answer, it seems lazy loading and auxiliary routes are not supported out of the box as they are rarely used together – Owen Kelvin May 19 '21 at 03:29
  • ok I think that explains everything. Thank you for your help. – user3626048 May 20 '21 at 11:05
0

Is it really important to have different routers? Can I ask what is the reason for that? I manage to get it work with one router. Can you check it?

Here is the updated example: https://stackblitz.com/edit/angular-nested-auxiliary-routes-w1tcn4?file=src/app/app.component.html

NeNaD
  • 18,172
  • 8
  • 47
  • 89
  • in my app I want to use Material Angular Sidenav https://material.angular.io/components/sidenav/overview with some static options on side panel, below some route-dependent component (second outlet) and main router outlet on content element. Is there any solution to do that without auxiliary router outler? – user3626048 May 18 '21 at 18:22
  • Can you elaborate? You will have Angular Sidenav with some options. You will have router outlet with for the content. What else? I don't get the part with `route-dependent component (second outlet) `. – NeNaD May 18 '21 at 19:07
  • something like this: https://i.postimg.cc/TY4c8R7k/project.jpg - e.g. primary outlet should show clients list component and secondary outlet should show clients form. menu component is the same for all routes – user3626048 May 18 '21 at 20:59
  • Should auxiliary router change content based on content from main router or independently? – NeNaD May 18 '21 at 22:08
  • I think is would be enought if primary and secondary outlets change together so continuing my example: route /ser/clients should show clients list in primary outlet and clients form in secondary; on other route like /ser/containers should show containers list in primary outlet and containers form in secondary outlet etc. – user3626048 May 19 '21 at 09:39