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

Utilizing middleware with express in the proper manner

Hello there! I'm just double-checking to see if I am using the correct method for implementing middleware in my simple express app. Specifically, I am trying to ensure that the email entered during registration is unique. Here's an example of wha ...

Improving the App() function in React and Typescipt

When working on my React/Typescript app, I encountered a challenge with the length of the code in one of the sections. Despite watching tutorials and searching for solutions, I couldn't find a clear way to refactor it. The specific issue is with refa ...

Create an Array of Objects by Sharing Your Post

Can someone guide me on the correct way to post my data here? I have been encountering errors while trying to insert data into user.SavedMachines.Id and user.SavedMachines.Date. I attempted using user.SavedMachines.Id = req.body.SavedMachinesId and user. ...

Understanding the integration of sass with webpack in an Angular 4 project

Is it possible to reference a sass file instead of a css file directly in the index.html? If so, how does webpack compile the sass into a css file? Additionally, what is the most effective way to bundle the sass file when building the application? The ve ...

Utilizing and transmitting contextual information to the tooltip component in ngx-bootstrap

I am currently working on integrating tooltips in ngx-bootstrap and trying to figure out how to pass data to the ng-template within the tooltip. The documentation mentions using [tooltipContext], but it doesn't seem to be functioning as expected. Belo ...

Find Mongoose model that doesn't belong to a specific field type

I have encountered an issue while querying a model using mongoose where the type is not an array. Recently, I made a change to one of the fields in my model (lastSeen) from being a date type to an array of dates. Now, I need to retrieve previous documents ...

The parameter 'any' cannot be assigned to the parameter 'never' - Array provided is incompatible

Currently delving into TypeScript and encountering an issue while setting a reducer in redux Toolkit. Here's the code snippet in question: const testSlice = createSlice({ name: "test", initialState: [], reducers: { callApi: (state, ...

Error: Module not found - Unable to locate 'dropzone'

Since migrating from Angular 4.4 to Angular 8.0, I encountered the following issue: ERROR in ./src/attributes/import/import.component.ts Module not found: Error: Can't resolve 'dropzone' in 'C:....\src\attributes\imp ...

The phrase 'tsc' is not identified as a valid cmdlet, function, script file, or executable program

Recently, I attempted to compile a TypeScript file into a JavaScript file by installing Node.js and Typescript using the command "npm install -g typescript". However, when I tried to compile the file using the command tsc app.ts, an error occurred: tsc : T ...

Express.js - Is there a way to serve distinct static directories for production and development environments?

My goal is to serve the ../client directory while in development, which contains the current files being edited. However, during production, I need to serve a folder called ../client/dist. How can I achieve this? I attempted to use a simple if condition, ...

What is the process for obtaining a flattened tuple type from a tuple comprised of nested tuples?

Suppose I have a tuple comprised of additional tuples: type Data = [[3,5,7], [4,9], [0,1,10,9]]; I am looking to develop a utility type called Merge<T> in such a way that Merge<Data> outputs: type MergedData = Merge<Data>; // type Merged ...

Is it possible to visually distinguish the selected mat-grid-tile? Particularly when they are being created dynamically

On the user interface, I have a dynamic display of mat-grid-tile within a mat-grid-list. These tiles change in number and data based on backend values. When a user clicks on a mat-grid-tile, it triggers a function that receives the tile's data. My goa ...

Steps to resolve the issue of being unable to destructure property temperatureData from 'undefined' or 'null' in a React application without using a class component

CODE: const { temperatureData } = state; return ( <> <div className="flex flex-row"> {temperatureData.map((item, i) => ( <div className="flex flex-auto rounded justify-center items-center te ...

When the variable type is an interface, should generics be included in the implementation of the constructor?

Here is a code snippet for you to consider: //LINE 1 private result: Map<EventType<any>, number> = new HashMap<EventType<any>, number>(); //LINE 2 private result: Map<EventType<any>, number> = new HashMap(); When the ...

Issues with TypeScript arise when transferring arguments between functions

Encountering a TypeScript error due to this pattern: Error message: 'Argument of type '(string | number)[]' is not assignable to parameter of type 'string[] | number[]' function foo(value: string | number) { return bar([va ...

Tips for effectively mocking a service class in a hybrid Angular project to facilitate unit testing

I'm currently working on a hybrid Angular project, but I've encountered some challenges with unit testing. Despite trying out this solution, it doesn't seem to be effective for my particular project. I keep receiving an error when running ...

Creating a personalized connect function in Typescript for react-redux applications

Currently, I am in the process of migrating a large and intricate application to Typescript. One specific challenge we are facing is our reliance on createProvider and the storeKey option for linking our containers to the store. With over 100 containers in ...

Exploring the intricacies of Node-Craigslist syntax

Greetings! I am currently utilizing the node-craigslist package found at https://github.com/brozeph/node-craigslist and I am in need of assistance with some syntax related to the details method. The documentation provides the following example: client . ...

The custom form input in Angular2 is throwing an error because it is trying to access the property 'name' of an

Upon switching to the latest Angular version 2 final, I encountered the following error Uncaught TypeError: Cannot read property 'name' of undefined This is my customized input import { Component, EventEmitter, Provider, forwardRef } from &a ...

Intellisense from @reduxjs/toolkit is not showing up in my VS Code editor

My experience with vscode is that intellisense does not recognize @reduxjs/toolkit, even though the code itself is functioning correctly. I have already installed the ES7+ React/Redux/React-Native snippets extension from here. Here are a couple of issues ...