I want to load routes for the @RouteConfig Dynamically from a service which fetches in format JSON,
[
{ "path" : "/about" , "name" : "About" , "component" : "AboutComponent" },
{ "path" : "/contact" , "name" : "Contact" , "component" : "ContactComponent" }
]
Following is the code for pushing it into the RouteDefinition Array,
for (let i = 0; i < data.length; i++) {
//console.log(data[i].path+" "+data[i].name+" "+data[i].component);
this.routeConfigArray.push({ //routeConfigArray : RouteDefinition
'path': data[i].path,
'name': data[i].name,
'component': data[i].component
});
this._router.config(this.routeConfigArray); // THIS FAILS TO CONFIG PATHS ON ROUTER
}
The 'component':data[i].component
requires Classname, where as it recieves a it via a String class. How do i convert the string containing classname into a class??
Also i have tried the Route class using :
this.routeConfigArray.push(new Route({path: data[i].path, name: data[i].name, component:data[i].component}));
Console Error:
Component for route "/about" is not defined, or is not a class. i have tried numerous ways like using
eval("new "+data[i].component+"()); || new window[data[i].component] .
I am stuck at this and really confused as to how to resolve this.
You could use the another approach that the one from @Pierre and @Pratik based on a method that returns the name of classes:
In your component you can then configure your routes dynamically like this:
This requires to know by advance potential components that can be involved in routing.
See this plunkr for demo: https://plnkr.co/edit/KKVagp?p=preview.
See this question:
You are too good @PierreDuc , i was just looking at regex to build the same function, some edits i would like to point out to bring it in working state....
Thankyou once again dude, its now in a running mode!!! Phew!
TypeScript compiles imports into javascript in a certain way, you can try something like this to be able to use
eval()
(cringe). This obviously won't work if typescript compiles differently, but it is fun to check out if this works any ways :)ADDENDUM
As addition to your own solution with using a
AsyncRoute
, I believe you actually got quite a good solution going on. Perhaps if you place all the pages in a certain way, you can extract theresource
location from thepath
, but that is not necessary. (i mean to get from thepath
string/about
to theresource
string./app/about/about.component
shouldn't be hard with a small algorithm. But that might be something for an update.Anyways, you can try something like this with the
AsyncRoute
warning: untested code ahead
Update to the first above scenario : The above dynamically loads routes on the UI, but for that to happen i do have to mention it in my AppComponent
But this defeats the purpose 'Dynamic Loading', as i have to know which components would be requested and also cannot lazy load them. Say i do that for 500 components, i have to load these 500 components and then just from a JSON mentioned above i pick which has to be loaded on the UI.
Solution(Completed And Tested) ==> I now do not have to mention the components i want to load in any import statement neither in any Directive. Thererby making it lazy loading and Completely Dynamic
How By Using AsyncRoute Class.
Here's my new JSON
//"route" is to map it to [routerLink]="['/Home']" & "resource" is the actual path of component
Now to the code, here i fetch this JSON and add it to the routeConfigArray : RouteDefinition[] and call the Router's .config(routeConfigArray)
And thats how it works!!!