I'm encountering an issue with one of my routes not loading correctly in Angular 4 Universal

I have been working on implementing Universal and I believe I've made significant progress. My project is built on this seed. However, when I run "npm start", only the /about and /contact pages render successfully. The /home page does not render at all, and the request is canceled with a status of "canceled" in the Network tab of the developer tools. You can find the full repository here (please note that it is the "@ng-bootstrap" branch). It would be greatly appreciated if someone could take a look at it. It's challenging to identify the bug without any error messages.

server.ts:

// src/server.ts
import 'reflect-metadata';
import 'zone.js/dist/zone-node';
import { renderModuleFactory } from '@angular/platform-server'
import { enableProdMode } from '@angular/core'
import { AppServerModuleNgFactory } from '../dist/ngfactory/src/app/app.server.module.ngfactory'
import * as express from 'express';
import { readFileSync } from 'fs';
import { join } from 'path';

const PORT = process.env.PORT || 4000;

enableProdMode();

const app = express();

let template = readFileSync(join(__dirname, '..', 'dist', 'index.html')).toString();

app.engine('html', (_, options, callback) => {
  const opts = { document: template, url: options.req.url };

  renderModuleFactory(AppServerModuleNgFactory, opts)
    .then(html => callback(null, html));
});

app.set('view engine', 'html');
app.set('views', 'src')

app.get('*.*', express.static(join(__dirname, '..', 'dist')));

app.get('/about*', (req, res) => {
  res.render('index', { req });
});

app.get('/contact*', (req, res) => {
  res.render('index', { req });
});

app.get('/home*', (req, res) => {
  res.render('index', { req });
});

app.listen(PORT, () => {
  console.log(`listening on http://localhost:${PORT}!`);
});

home.module.ts:

// src/app/home/home.module.ts
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { HomePageComponent } from './home-page/home-page.component';

@NgModule({
  imports: [
    CommonModule,
    RouterModule.forChild([
      { path: '', component: HomePageComponent, pathMatch: 'full' }
    ])
  ],
  declarations: [HomePageComponent]
})
export class HomeModule { }

home-page.component.ts:

// src/app/home/home-page/home-page.component.ts
import { Component, OnInit } from '@angular/core';

import { Exchange } from '../../exchange';
import { ExchangeService } from '../../exchange.service';
import { ClockService } from "../../clock.service";

@Component({
  selector: 'app-home-page',
  templateUrl: './home-page.component.html',
  styleUrls: ['./home-page.component.scss']
})
export class HomePageComponent implements OnInit {
  exchanges: Exchange[] = [];
  myDate: Date;

  constructor(private exchangeService: ExchangeService,
              private clockService: ClockService
             ) {}

  ngOnInit(): void {
    this.exchangeService.getExchanges()
      .then(exchanges => this.exchanges = exchanges);

    this.clockService.utcTime(this.exchanges);
    setInterval(() => {
      this.myDate = this.clockService.utcTime(this.exchanges)[0];
      this.exchanges = this.clockService.utcTime(this.exchanges)[1];
    }, 1000);

    this.clockService.fetchExchanges();
  }

  buttonTest(): any {
    this.clockService.testingfunction();
  }
}

app.module.st:

// src/app/app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import {NgbModule} from '@ng-bootstrap/ng-bootstrap';

import { AppComponent } from './app.component';
import { TitleComponent } from './title.component';
import { MetaDescriptionComponent } from './meta-description.component';
import { NavbarComponent } from "./navbar/navbar.component";
// import { SortPipe } from "./sort.pipe";

import { ClockService } from "./clock.service";
import { ExchangeService } from "./exchange.service";

export { AppComponent, TitleComponent, MetaDescriptionComponent };

@NgModule({
  declarations: [
    AppComponent,
    NavbarComponent,
    TitleComponent,
    // SortPipe,
    MetaDescriptionComponent
  ],
  imports: [
    NgbModule.forRoot(),
    BrowserModule.withServerTransition({ appId: 'cli-universal-demo' }),
    RouterModule.forRoot([
      { path: 'home', loadChildren: './home/home.module#HomeModule' },
      { path: 'about', loadChildren: './about/about.module#AboutModule' },
      { path: 'contact', loadChildren: './contact/contact.module#ContactModule'},
      { path: '**', redirectTo: '', pathMatch: 'full' },
    ])
  ],
  providers: [ExchangeService, ClockService],
  bootstrap: [AppComponent, TitleComponent, MetaDescriptionComponent]
})
export class AppModule { }

Answer №1

It seems like the paths in your configuration do not align with the component paths.

RouterModule.forRoot([
  { path: 'home', loadChildren: './home/home.module#HomeModule' },
  { path: 'about', loadChildren: './about/about.module#AboutModule' },
  { path: 'contact', loadChildren: './contact/contact.module#ContactModule'},
  { path: '**', redirectTo: '', pathMatch: 'full' },
])

Consider updating it to:

RouterModule.forRoot([
 { path: '', loadChildren: './home/home.module#HomeModule' },
 { path: 'about', loadChildren: './about/about.module#AboutModule' },
 { path: 'contact', loadChildren: './contact/contact.module#ContactModule'},
 { path: '**', redirectTo: '', pathMatch: 'full' },
 ])

The issue lies in the fact that your components NgModule is pointing to '' instead of 'home'

RouterModule.forChild([
  { path: '', component: HomePageComponent, pathMatch: 'full' }
])

For detailed examples, check out these files in the cli-universal demo home.module.ts and app.module.ts

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When bcrypt is used to hash two identical strings, the comparison result may be undefined

Having an issue with hashing and comparing two identical strings to verify a password using the bcrypt package in nodeJS. When I try to use the bcrypt.compare method, it returns undefined! Below is my code snippet: var akbar, akbar2; bcrypt.hash(' ...

Errors from NestJS microservice class validator are visible in the docker container but do not appear in the API response

Seeking assistance with displaying validation errors in my NestJS project using class validator. This is my first time working with microservices and NestJS, as it's for a school project. Errors from my 'user' microservice container are not ...

How can I maintain form data submission to the server without triggering a redirect?

I am currently in the process of developing a web application that utilizes the Spotify API. My goal is to utilize the user input data to trigger calls to the Spotify API on the server and then relay the results back to the front end. However, I have encou ...

Send the current state of React to an Express server

I've attempted various methods to accomplish this task, but no matter what I try, I always end up with the same outcome. When I start the server and make my first post request, it doesn't seem to work because the state hasn't updated (at le ...

Incorporating Vaadin components into an Angular2-seed project

Hi there, I've been encountering an issue while trying to integrate Vaadin elements into my Angular2 seed project. The Vaadin team has recommended that I upgrade the systemjs.config.js file by specifying the path names for Vaadin elements like this: ...

Angular is sending a parameter with a null value, which is not supposed to happen

My filtering system used to work well with a code that displayed items of specific status. However, I had to modify it to match a select input requirement. <ul id="dropdown-basic" *dropdownMenu class="dropdown-menu" role="menu" aria-labelledby="button- ...

Capture a screenshot with Puppeteer at a random URL stop

I am facing an issue with my service nodejs running on Ubuntu, where I use puppeteer to capture screenshots of pages. However, the method page.screenshot({fullPage: true, type: 'jpeg'}) sometimes fails on random URLs without displaying any errors ...

Ways to utilize multiple tsconfig files within VS Code

My project structure in Visual Studio Code is fairly common with a client, server, and shared directory setup: ├── client/ │ ├── tsconfig.json ├── shared/ ├── server/ │ ├── tsconfig.json ├── project.json The tw ...

Error causes Node.js server to halt running

Having trouble with my server stopping and receiving this error. Any ideas on how to solve it or what it means? events.js:182 throw er; // Unhandled 'error' event ^ Error: read ECONNRESET at exports._errnoException (util.js:1024:11) ...

Steps to resolve security vulnerabilities found in Angular 12.0.3 through npm audit

Upon creating a fresh Angular 12.0.3 project, running npm audit immediately uncovers 8 high and 40 moderate vulnerabilities. # npm audit report css-what <5.0.1 Severity: high Denial of Service - https://npmjs.com/advisories/1754 fix available via `npm ...

Build a new datatable within an Angular component

Currently, I am working on an Angular 2 application where I have a module named Home with a component of the same name. HomeModule.ts: import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ...

angular failure to assign a variable to $scope

When communicating with the Node server, I am able to receive a response message in the controller. However, there seems to be an issue with assigning it properly. .controller('someCtrl', function(exportExcel){ $scope.clickEvent = function() ...

Sharing data between ejs and javascript files

When using Express, I have encountered an issue with passing a variable to an EJS file called "index.ejs". res.render("index",{passedUser:req.user.alias}) Although I am able to successfully print it using <%=passedUser%> in the EJS file, I require ...

When choosing the child option, it starts acting abnormally if the parent option is already selected in Angular

I am encountering an issue while trying to select the parent and its children in the select option. The concept is to have one select option for the parent and another for the child. I have parent objects and nested objects as children, which are subCatego ...

What is the best way to inject a service instance into the implementation of an abstract method?

In my Angular application, I have a service that extends an abstract class and implements an abstract method. @Injectable({ providedIn: 'root', }) export class ClassB extends ClassA { constructor( private service : ExampleService) { s ...

Is there a more efficient method to gather properties from an object into separate arrays without the need for using `map` twice?

Currently, my code block looks like this: res.json({ dates: rows.map(function (item) { return item.Date }), counts: rows.map(function (item) { return item.NewMembers }) }); While functional, I can't help but feel it is inefficient as the row ...

The Authorization header in POST and PATCH fetch requests is stripped by Typescript

I have developed an API in C# that utilizes JWT tokens for authorization. On the frontend, I store these tokens in local storage and retrieve them when making a request. GET or DELETE requests work seamlessly, as I can verify through console.log() that t ...

Encountering difficulty obtaining return value from asynchronous function, await behaving inconsistently in Vue API Service

I am in the process of developing a new service to interact with my API. I am not very familiar with async/await, but I have encountered a puzzling issue that doesn't seem to align with what I've read in the documentation. When attempting to use ...

The Express Router Middleware is triggered by unexpected paths

I am faced with a challenge in implementing Express Middleware to ensure that users are authorized for certain requests. However, not all requests require validation. In my router setup, the structure looks like this: // Routes that end in /transactions m ...

Angular TextInput Components don't seem to function properly when dealing with arrays

I am trying to create a collection of text input components with values stored in an array. However, when using the following code, the values seem to be placed incorrectly in the array and I cannot identify the bug. <table> <tr *ngFor="let opt ...