I have an application built on Angular 5 and Contentful. A service retrieves an Entry
of routes from Contentful as JSON and must feed those routes to a child routing module that is lazily-loaded. Obviously, the routes would need to be dynamically set inside the child routing module, as it should be possible to update their values from Contentful at any time.
The child router module, NewsRoutingModule, looks like this:
const newsRoutes: Routes = [
{ path: '', component: NewsComponent },
{ path: '**', component: 404Component }
];
@NgModule({
imports: [
RouterModule.forChild(newsRoutes),
...
],
declarations: [
NewsComponent,
NewsArticleComponent,
NewsCardComponent
],
...
})
export class NewsRoutingModule {
constructor(
private router: Router,
private languageService: LanguageService,
private contentfulService: ContentfulService
) {
this.loadRoutes();
}
loadRoutes() {
// Language Service is used to detect the locale. Contentful Service is used to pull content from Contentful.
this.languageService.events$.subscribe(locale => {
this.contentfulService
.getSearchResults('newsArticle', '', locale)
.then(response => {
// Content from Contentful returned as a response containing an array of Entry objects.
response.items.forEach((entry: Entry<any>) => {
let entryRoute = entry.fields.route;
let hasRoute = false;
// Check that the route doesn't already exist before adding it.
newsRoutes.forEach((angularRoute) => {
if (angularRoute.path == entryRoute) {
hasRoute = true;
}
});
if (!hasRoute) {
newsRoutes.push({path: entryRoute, component: NewsArticleComponent});
}
});
// Reset router's config at the end.
this.router.resetConfig(newsRoutes);
});
});
}
}
I encountered a few issues with this:
NewsRoutingModule
.NewsArticleComponent
that I am trying to assign for every new route from Contentful is not recognized. This is despite the fact that it is part of the declarations of @NgModule
.I see what you're trying to do, but there is a different process that should be applied in this situation
Lets say you have a site with the following main routes;
/home
/home/news
/home/news/article1
/home/news/article2`
The home
and home/news
would be your RouterModule.forRoot
routes
If an article route is activated, /home/news/article1
, this should load your NewsArticleComponent
- what you need for this is Angular Route Parameters
{ path: '/home/news/:id', component: NewsArticleComponent }
In the ngOnInit of the NewsArticleComponent
you can get the new article id, and retrieve the Entry from contentful. You might also want to look into Route Resolvers
, where you can retrieve the data from Contentful before loading the News Component
You will need to find example of Route Parameters, and also Route Resolvers. After that, it should be pretty straightforward
Note: I'm not sure why you are Lazy Loading the new article component. You usually only lazy load modules that are unlikely to be used very often, but in this case it's the main component of you application