Search code examples
angularrouter-outlet

Angular multiple <router-outlet> passing data


I have an app with a toolbar where I have a drop-down list and main menu, when clicking on of the main menu a component is loaded to the <router-outlet> (lazy-loaded)

some of the menus have a component that have a 2nd level navigation on the left and on the right a component is loaded when clicking the 2nd level navigation (the 2nd <router-outlet>) (not lazy-loaded)

What is the best way to pass data from toolbar to the components ?

whenever I choose a different value in the drop-down in the toolbar I need to get this value to component

I have tried multiple different ways using [state] in the router and using Input(), Output() (but it does not work with <router-outlet>) and then with events so that when I want the value in the component I send an event which I listen to in the toolbar and then toolbar emits the value which I listen to in the component. So from component emit value to toolbar so that it knows to emit value back.

I never got this working properly and it turned out to be quite complex for me. I was wondering is there an easier solution. In the components I have http calls which are called based on the value from the toolbar.

I got this strange situation that when I navigated away from the component and back the number of http calls increased every time. I never figured why this was happening even if I tried destroying the subscription in the component.

Any help much appreciated.

Thanks


Solution

  • I would use a service: https://angular.io/guide/component-interaction#parent-and-children-communicate-using-a-service

    In your case you should probably define a ToolbarService which should be {providedIn: 'root'}. (that way you make sure you have the same unique instance between lazy modules) This service should have a setFilterValues method that should be called from the Toolbar component. This method's implementation will do a subject.next(data) with the values.

    Then from each of the side components you'll subscribe to the same subject of the service (wrapper with .asObservable() like in the link above). In the subscription make the http call with the filter values. (best to link the 2 observables and do a switchMap between them rather than doing 2 subscribe callbacks)

    Make sure you unsubscribe from the service subject subscription inside the components, otherwise your components will keep making http calls even if they are removed from the page later on.