I am in the process of developing a web application that showcases news articles. My goal is to create a single-page app where users can view a list of article titles and then click on a title to read the full content without reloading the entire page.
I have successfully implemented this feature, but now I want to update the URL dynamically when an article is clicked, without refreshing the entire page. Despite following the guidance on child routing components and other resources, I keep encountering an error message in the console:
Cannot find primary outlet to load ''
Here is the code I have been working with:
app/app.routes.ts :
import { provideRouter, RouterConfig } from '@angular/router';
import { articlesRoutes } from './articles/articles.routes';
import { ArticlesComponent } from "./articles/articles.component";
const routes: RouterConfig = [
...articlesRoutes,
];
export const appRouterProviders = [
provideRouter(routes)
];
app/articles/articles.routes.ts :
import {ArticlesComponent} from "./articles.component";
import {RouterConfig} from "@angular/router";
import {ArticleDetailComponent} from "./detail/article-detail.component";
export const articlesRoutes: RouterConfig = [
{
path: '',
component: ArticlesComponent,
children: [
{
path: 'detail/:id', component: ArticleDetailComponent
},
]
}
];
app/articles/articles.component.html
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { ArticleService } from "./shared/article.service";
import { Article } from "./shared/article.model";
import { ArticleDetailComponent } from "./detail/article-detail.component";
import { ROUTER_DIRECTIVES } from '@angular/router';
@Component({
selector: 'fcso-articles',
templateUrl: 'app/articles/articles.component.html',
directives: [ROUTER_DIRECTIVES],
providers: [ArticleService],
})
export class ArticlesComponent implements OnInit {
articles: Article[] = [];
articleOpened: Article = null;
error: any;
constructor(
private articleService: ArticleService,
private router: Router) {}
getArticles() {
this.articleService
.getArticles()
.then(articles => this.articles = articles)
.catch(error => this.error = error);
}
ngOnInit() {
this.getArticles();
}
//function changing the hidden article and redirecting to URL
gotoDetail(article: Article) {
this.articleOpened = article;
this.router.navigate(['', '/detail', this.articleOpened.id]);
}
}
index.html
<body>
<!-- the main content (from app.component.ts) is not loaded from router -->
<fcso-main>
Loading...
</fcso-main>
</body>
app/app.component.html
<div class="container">
<div class="col-xs-12 col-md-8 col-md-offset-2 fcso-no-padding">
<div class="panel panel-default">
<div class="panel-body">
<h1 class="text-center">Title</h1>
</div>
</div>
<!-- this router outlet should show articlesComponent -->
<router-outlet></router-outlet>
</div>
</div>
app/articles/articles.component.html
<div class="panel panel-default" *ngFor="let article of articles">
<div class="panel-heading fcso-panel-heading" *ngIf="article !== articleOpened" >
<h3 class="text-center fcso-open-panel" (click)="gotoDetail(article)">{{article.title}}</h3>
</div>
<!-- router-outler is hidden to boost angular perfs and avoid troubles -->
<router-outlet *ngIf="article === articleOpened"></router-outlet>
</div>
I have attempted to consolidate the content of articles.routes.ts directly into app.routes.ts without success. While the list of articles loads successfully, the child content does not load, resulting in the following error message:
Cannot find primary outlet to load 'ArticleDetailComponent'
Even utilizing routerConfig in the .component.ts file did not yield a different outcome. I am unsure of the steps required to display the child (ArticleDetailComponent) in the designated location upon clicking the title and modifying the URL. Any guidance on resolving this issue would be appreciated.