Show error page when catch error (without redirect) angular 2+

Viewed 570

I have a blog with articles. When I am on specific article on blog page (with url /blog/article-title) I have a spinner and make a get request, when it is successful, I show info related to this article. But if I type in url , for example, /blog/123 (I don't have this artilce) I have a spinner and error in console. What do I want is to show error page, but with incorrect url (blog/123) How can I do this?

app-routing.module

const routes: Routes = [
    {
        path: '',
        loadChildren: () => import('./main-page/main-page.module').then(m => m.MainPageModule),
    },
    {
        path: 'blog',
        loadChildren: () => import('./blog-page/blog-page.module').then(m => m.BlogPageModule),
    },
    {
        path: '**',
        loadChildren: () => import('./error-page/error-page.module').then(m => m.ErrorPageModule),
    },
];

blog-page-routing.module

export const routes: Route[] = [
    {
        path: '',
        component: BlogPageComponent,
        children: [
            {
                path: '',
                component: ArticlesPageComponent,
            },
            {
                path: ':id',
                component: ArticlePageComponent,
            },
        ],
    },
];

article-page

public ngAfterViewInit(): void {
        if (!this.article) {
            this.articleSubscription = this.route.paramMap
                .pipe(
                    switchMap(params => {
                        this.isLoadingInProgress = true;
                        return this.dataService.getArticleById(params.get('id'));
                    }),
                )
                .subscribe(response => {
                        this.article = response.currentArticle;
                        this.prevArticle = response.prevArticle;
                        this.nextArticle = response.nextArticle;
                        this.navigationModel = {
                            prevItem: {
                                route: this.prevArticle ? `blog/${this.prevArticle.id}` : null,
                                text: this.prevArticle && this.prevArticle.title,
                                image: this.prevArticle && this.prevArticle.mainImageUrl,
                            },
                            nextItem: {
                                route: this.nextArticle ? `blog/${this.nextArticle.id}` : null,
                                text: this.nextArticle && this.nextArticle.title,
                                image: this.nextArticle && this.nextArticle.mainImageUrl,
                            },
                        };
                        this.isLoadingInProgress = false;
                        this.changeDetection.markForCheck();
                    },
                    error => {
                        this.isLoadingInProgress = false;
                    });
        }
    }

UPDATED: The error page is shown when url is incorrect (localhost:4200/123) but it doesn't work with blog url (localhost:4200/blog/123)

2 Answers

A simple solution is add an error field in your component:

error = false;
public ngAfterViewInit(): void {
        if (!this.article) {
            this.articleSubscription = this.route.paramMap
                .pipe(
                    ...
                )
                .subscribe(response => {
                        ...
                        this.isLoadingInProgress = false;
                        this.changeDetection.markForCheck();
                    },
                    error => {
                        this.error = true;
                        this.isLoadingInProgress = false;
                    });
        }
    }

And use error in template

<div *ngIf="error; else content"><app-error>...</app-error></div>
<ng-template #content>
  ...
</ng-template>

If you do not want to write the same boilerplate at each time, you can think of a notification system or an overlay / alert message

Yes, It is working as expected because localhost:4200/blog/123 isn't invalid URL routing error catch invalid URLs. But when you reached the ngAfterViewInit in article-page that means for sure it is a valid routing.

Solution is to handle the invalid dynamic ids inside the view and could be done in different ways:

  • Redirect to error page.
  • Alert/Popup Message
  • Create Inline error page and use as follows better than *ngIf to avoid creating/removing from DOM:

<div [hidden]="!showError">
  <h1>Error Message</h1>
</div>  

<div [hidden]="showError">   
/ /Articles
</div>

Related