Encountered a problem with AngularUniversal prerendering: UnhandledPromiseRejectionWarning: Unable to locate NgModule metadata for 'class{}'

Objective

The task may seem lengthy, but it's straightforward!

Currently, I am utilizing Angular Universal for Server-Side Rendering (SSR) by following a tutorial. The Universal/express-engine has been installed, main.js is generated in the dist/projectname/server directory, and I have created a prerender.js folder in the project root.

Issue

Upon running npm run prerender, the process initiates pre-rendering until encountering the following error:

Error: No NgModule metadata found for 'class{}'

This leads to several UnhandledPromiseRejectionWarning messages and errors throughout the process.

Intended Outcome

I aim to pre-render the HTML of our primary route and save it to a text file.

Attempted Solutions

This approach involved deleting the chained .catch(err...) function of the bootstrap in main.ts, resulting in the same error.

Another method included deleting node-modules and package.json, then running npm install, ng build, ng serve, which also led to the same error.

A different fix advised updating AngularCLI and Webpack, yet the error persisted.

Software Versions

Angular CLI: 10.0.0
Node: 12.16.3
OS: win32 x64

Angular: 10.0.0
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, platform-server
... router
Ivy Workspace: <error>

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.900.7
@angular-devkit/build-angular     0.901.9
@angular-devkit/build-optimizer   0.901.9
@angular-devkit/build-webpack     0.901.9
@angular-devkit/core              9.0.7
@angular-devkit/schematics        10.0.0
@angular/cdk                      9.2.4
@angular/fire                     6.0.2
@ngtools/webpack                  9.1.9
@nguniversal/builders             9.1.1
@nguniversal/common               9.1.1
@nguniversal/express-engine       9.1.1
@schematics/angular               10.0.0
@schematics/update                0.1000.0
rxjs                              6.5.5
typescript                        3.9.5
webpack                           4.43.0

Files Involved

  1. prerender.ts
import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import {renderModuleFactory} from '@angular/platform-server';
import {writeFileSync} from 'fs';

const {AppServerModuleNgFactory} = require('./dist/hibernio/server/main');

renderModuleFactory(AppServerModuleNgFactory, {
    document: '<app-root></app-root>',
    url: '/'
})
.then(html => {
    console.log('Pre-rendering successful, saving prerender.html');
    writeFileSync('./prerender.html', html);
})
.catch(error => {
    console.error('Error occurred:', error);
});
  • server.ts
Import statements...

Content of server.ts...
  • main.server.ts
Import statements...

Other code snippets...
  • tsconfig.server.json
Configuration details...
  • angular.json
Project setup details...
  • package.json
Information about npm packages used...

Additional Note

An issue related to Ivy was identified by David. Enabling Ivy in tsconfig.json under compilerOptions > enableIvy resulted in a series of errors related to fontawesome. Previously, disabling Ivy was necessary when integrating fontawesome due to conflicts. Now, finding a solution to make both packages operational together with Ivy enabled is challenging.

Special thanks to David for flagging the Ivy complication.

Answer №1

To solve the initial issue of not finding a NgModule, make sure Ivy is enabled.

If you encounter the error related to an invalid constructor parameter decorator, it may be due to using the outdated package angular-font-awesome which is not compatible with Ivy.

In that case, uninstall the package using the command

npm uninstall angular-font-awesome -S
and stick to the following fortawesome packages:

"@fortawesome/angular-fontawesome": "^0.6.1",
"@fortawesome/fontawesome-free": "^5.13.1",
"@fortawesome/fontawesome-svg-core": "^1.2.29",
"@fortawesome/free-brands-svg-icons": "^5.13.1",
"@fortawesome/free-regular-svg-icons": "^5.13.0",
"@fortawesome/free-solid-svg-icons": "^5.13.1",

Please note: It is unnecessary to create the prerender.ts file as mentioned in a previous comment. Instead, add routes to render in your angular.json and execute ng run prerender.

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

Adding a component dynamically with a link click in Angular: A step-by-step guide

I am encountering an issue with my web application setup. I have a navigation bar, a home page with left and right divs, and a view-associates component. My goal is to dynamically add the view-associates component into the home's right div when a spec ...

Ways to identify when a chemical reaction has taken place?

I have developed a Discord bot that interacts with an API related to a game server panel. The bot has tasks to start, restart, stop, and kill the server. I want to enable end users to trigger these tasks by reacting to a specific embed posted by the bot. ...

Ways to retrieve several parameters from a controller using Ajax Jquery in Codeigniter

I need to retrieve a list of images from a folder based on a specific ID. Currently, I am able to get the file names but I also require the upload path. Is there a way to obtain both sets of data using a single function? Javascript Code: listFilesOnServ ...

Express throwing an error: connection closed unexpectedly

My Node server keeps crashing when a client refreshes the page while it is still loading, leading to the socket being terminated mid-request. The specific error message I receive is: [ERROR] - Error: socket hang up at createHangUpError (http.js:1472:15 ...

Looking to retrieve a single data point from [object][object]

Presented here is an angular component: import { Component, OnInit } from '@angular/core'; import { Hall } from 'src/app/models/hall.model'; import { HallService } from 'src/app/services/hall.service'; import { ActivatedRoute, ...

I am experiencing an issue where my React application is not loading the fonts when utilizing `type: 'asset/resource'` to load fonts within a CSS file. Can anyone provide guidance on

I'm encountering an issue with my webpack setup where fonts are not being loaded when using type: 'asset/resource'. Actually, there are several problems arising from the use of asset/resource, but let's focus on this particular issue fo ...

Encountering the error message "Unable to retrieve /todos."

I recently built a basic Express application and am currently testing the POST route using Postman. However, I keep encountering an error message saying Cannot GET /todos. Any thoughts on what might be causing this issue with the following code? const ex ...

What is the reason behind the mandatory credentials option for the CredentialsProvider?

When using NextAuth.js with a custom sign in page, some code examples for the credentials provider do not include the credentials option in the CredentialsProvider. According to the documentation (here), the credentials option is meant to automatically "ge ...

Implementation of async operations using while loop in Node.js

I'm facing an issue with my code snippet. Here's what it looks like: Rating.find({user: b}, function(err,rating) { var covariance=0; var standardU=0; var standardV=0; while (rating.length>0){ conso ...

Is it possible to retrieve the createdAt timestamp without displaying the 'GMT+0000 (Coordinated Universal Time)'?

After conducting an extensive search, I have yet to find a satisfactory answer. My goal is to configure it without including the CUT time. {name: "Registered:", value: `${user.createdAt}`}, {name: "Joined:", value: `${message.guild.joinedAt}`} Presently, ...

Personalize your Client-Id for Paypal

Currently integrating PayPal's Smart Payment Buttons into my Angular project. The index.html file contains the following script: <script src="https://www.paypal.com/sdk/js?client-id=MY_CLIENT_ID"> </script> I am working on developi ...

``Look at that cool feature - a stationary header and footer that stay in place

I'm seeking advice on how to design a website with a fixed header and footer that remain consistent across all pages, with only the content area altering. I've come across a site as an example - , but couldn't figure out how it was done even ...

What is the best way to save dropdown selection to a MySQL database using Node.js and EJS?

I am currently working on a Node.js project where I need to write data into a MySQL database using a post function. One of the requirements is to have certain values displayed as dropdown options on the add page. However, my current implementation only all ...

PHP is receiving data from $.post in an invalid format

I am facing a challenge in sending a JavaScript Object() to a PHP file in the correct format that $.POST requires. The PHP file does not establish any $_POST[] variables, which suggests that I may be transmitting the data in an improper format. JS: $(&ap ...

Using jQuery each with an asynchronous ajax call may lead to the code executing before the ajax call is completed

In my jQuery script, I utilize an each loop to iterate through values entered in a repeated form field on a Symfony 3 CRM platform. The script includes a $.post function that sends the inputted value to a function responsible for checking database duplicat ...

access various paths to distinct iframes

<?php // Specify the directory path, can be either absolute or relative $dirPath = "C:/xampp/htdocs/statistics/pdf/"; // Open the specified directory and check if it's opened successfully if ($handle = opendir($dirPath)) { // Keep readin ...

Loading javascript libraries that are contained within an appended SVG document

I am currently working on developing a browser-based SVG rasterizer. The unique aspect of this project is that the SVG files may contain JavaScript code that directly impacts the output, such as randomly changing element colors, and utilizes external libra ...

Compiling with tsc --build compared to tsc --project

I'm currently working on converting a subproject to TypeScript within my monorepo. Within my npm scripts, I initially had: "build-proj1":"tsc --build ./proj1/tsconfig.json" Although it did work, I noticed that the process was unus ...

Exploring the Benefits of Utilizing the tslint.json Configuration File in an Angular 6 Project

https://i.stack.imgur.com/j5TCX.png Can you explain the importance of having two tslint.json files, one inside the src folder and one inside the project folder? What sets them apart from each other? ...

What's the best way to display a bootstrap modal window popup without redirecting to a new page?

I am having trouble implementing a modal window that will display validation errors to the user when they submit a form. Currently, the window is opening as a new view instead of overlapping the existing form's view. How can I adjust my code so that t ...