Archive for June, 2023

June 22nd, 2023
3:05 pm
Angular – Dynamic Routing between Angular Elements aka Web Components

Posted under Angular & Routing & Web
Tags

Following on from my previous post on dynamic routing fundamentals, the ability to route dynamically across angular elements, i.e. to use the router to route to a dynamically loaded angular element, seems to be a sticking point.

Previously, I developed a web components example where a ‘fabric’ component was responsible for dynamically creating web components and displaying them. This did not use angular routing, but dynamically added them to the dom based on menu selections or url parameters. Subsequently, I wanted to investigate whether I could use angular routing to implement this instead.

I have found a number of examples of varying degrees of complexity, which go at least some of the way. However, I have not seen what I would term a reasonably straightforward, out-of-the-box solution, which does not involve too much deep diving into the internals of angular.

The following examples have been examined to date:

A complex dynamic one here with perhaps useful ideas but actual components still appear to be declared in the angular app:
https://medium.com/ngconf/dynamic-component-generation-in-lazy-loaded-routes-d2e0f9e89c57
The code is here:
https://github.com/theAlgorithmist/Angular8LazyLoadDynamic

Some specific ideas in this one here but still some way to go IMO…
https://medium.com/@timon.grassl/how-to-use-routing-in-angular-web-components-c6a76449cdb

This one perhaps looks the most promising, and may have all the relevant techniques needed, but It still appears to have statically declared component objects which are used dynamically in a dynamic order…
https://snyk.io/advisor/npm-package/angular-elements-router

Some more research is needed on this as I am keen to fine the simplest solution which uses as little as possible of the deeper features of angular.

 

Comments Off on Angular – Dynamic Routing between Angular Elements aka Web Components

June 22nd, 2023
10:47 am
Angular Dynamic Routing

Posted under Angular & Knowledge Base & Routing & Web
Tags ,

One of my goals is to be able to dynamically create routes based on configuration data, typically loaded at pre-init time using an app initialiser.

Two approaches I have seen to doing this are as follows:

  1. Using a custom Injector to use code to inject the routes.
    This is done in this example here. The code for it is available here.
  2. Using Router.resetConfig() to change the routes after initially creating them.
    This is done in this example here. The code for it is available here.
    It is also done in this example here, in the app initialiser.

Both are dynamic, but method 1/ with the injector runs before any app initialiser, so would not be suitable for my needs (I verified this with a simple test with console logging). If this were used, any dynamic config would need to be fetched within the injector code or called directly from it. Method 2/ can be used after the app initialiser – I tried calling it successfully from the ngOnInit lifecycle hook in the app component which worked fine.

This example here uses method 1/, and the code for it is on github here. I downloaded the code and modified the original version, as it contains errors in the time of day checking code. I then saved the project to bitbucket. I branched it and modified it again to use resetConfig as above from ngOnInit, and removed the injector mechanism. This also worked fine.

Whilst these approaches allow dynamic creation of the routes, they assume that the routed components are known to the application or declared in it in some form. The basis of the standard approach to routing is that the component class referred to in the route is looked up, and its selector is extracted and used to create the component tag dynamically, inserting it after the appropriate <router-outlet>. This would not work in the case of angular elements, i.e. W3C web components. These are entirely dynamic and my examples which use these in the past have the element name/component tag defined dynamically as part of the config, along with the names of the scripts to be loaded to create the web component. Another approach will need to be investigated to look into routing of angular elements.

Comments Off on Angular Dynamic Routing

June 22nd, 2023
8:08 am
Angular Routing

Posted under Angular & Knowledge Base & Routing & Web
Tags ,

These points were found whilst trying some angular router examples.

Examples tried were these. Note that they are all on Stackblitx, and therefore zips can be downloaded.
It is not obvious how, but just make sure the project panel is open by clicking on the 2-page icon near the top left. Then click on the small cloud icon containing the down arrow, on the RHS of the project panel title.

  1. https://www.tektutorialshub.com/angular/angular-routing-navigation/
  2. https://stackblitz.com/edit/angular-ivy-spsz1g?file=src%2Fapp%2Fapp.component.ts
    Note that this one above is angular 15 so pretty up to date
Here are the official angular ones:
  1. Basic one with just 2 router states/2 buttons
    https://angular.io/guide/router-tutorial
  2. Full Tour of Heroes tutorial
    https://angular.io/guide/router-tutorial-toh 
    This above one is angular 16 so latest
 
Points on configuring and using routes:
  1. Routes are defined using RouterModule.forRoot. In some examples the route definitions/routes array is defined in app.module.ts (as in the basic angular.io example above). More typically the routes array is defined in a separate file to separate the concerns, such as app-routing.module.ts or app.routes.ts. It can then either be exported from this file and referenced in app.module.ts via RouterModule.forRoot (as in the tektutorials example above), or RouterModule.forRoot is itself also in the separate file defining the routes (as in the full Tour of Heroes example above, in app-routing.module.ts).

  2. In all the examples, routing is done by creating a component and placing it as a sibling of the <router-outlet>tag, immediately after <router-outlet>. The created component is never placed as a child of the <router-outlet>. As per the full Heroes tutorial, <router-outlets> can be nested where required – a component activated from a <router-outlet> can then use other routes to activate further child components etc.

  3. When refreshing e.g. a child page on zen apache or http-server, I got 404 errors. It is necessary to tell the server to redirect to e.g. index.html or whatever you are using, to get the routing to work. This was not the case when using “ng serve” as this takes care of the issue for you automatically. The same problem happens if you enter a url manually or from a link, to go to a detail child route page. This angular.io deployment page explains how to do this for various servers, including apache as used by Zen in my case. In my case I tested on Zen and needed to edit .htaccess as per the instructions. For this to work, I had to change the path in the instructions to the correct subdomain index.html file or it still failed. I also created a child .htaccess file in the subdomain folder where my app was hosted. This ran in addition to the main .htaccess, and it all worked fine. I did notice that the lowest child hero pages on the full tour of heroes example above still failed with a 404. However, they also failed with a 404 when served via “ng serve”, so I concluded that this was a coding issue in the example and did not investigate further. My .htaccess for the full heroes example under zen was as follows:-
RewriteEngine on

RewriteOptions inherit

# BEGIN Angular Routing

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR] 
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d 
RewriteRule ^ - [L] 

# If the requested resource doesn't exist, use index.html 
RewriteRule ^ /angular-router/angular-full-heroes-example/index.html

# END Angular Routing


When a route is activated, its target component is always recreated and any previous component for the corresponding <router-outlet> is destroyed. I confirmed this with all the above examples by logging in the ngOnInit and ngOnDestroy life cycle methods. Components are not switched in and out by showing and hiding.

For me, if I wanted to use web components with routing, I had thought that dynamic target component recreation might create an overhead as they would need creating each time, by dynamic loading/running of all their run time js scripts (e.g. main.js, runtime.js, vendor.js). I had considered using componentless routes to avoid this overhead, and do my own creation in a route resolver.
 
However, in fact, it looks like the running of their creation scripts is a separate operation that only needs doing once. The angular router just appears to create and delete element tags from the dom, so the deletion of a tag and subsequent recreation should not require reloading the scripts, so if correct I could do the script loading in a route resolver once, the first time the script is loaded (or earlier if I am doing eager loading). I could then let angular do what it likes re adding and removing elements.
 
I intend to try this out with my existing web components/microapps demo – at present it hides/shows microapps when switching between them, but it looks like I could change this to removing/recreating the microapp elements, but only loding the script once. This would easily validate this idea.
 
In addition to this I would want to make the component name in a route definition dynamic and load it server side, and perhaps also dynamically load the route definition or at least dynamically create it from server side parameters and a template definition. This appears to be possible and this post here looks into it. This other post also looks into it with lazy loading. Significantly more investigation is needed on this.
 
 
 
 

Comments Off on Angular Routing