Angular Universal build stuck on rendering page while waiting for API response

I'm currently developing a compact web application using the angular universal starter in combination with pokeapi. To enhance performance and reduce API requests, I intend to implement pre-rendered pages since the data displayed remains mostly static. For instance, I have integrated a list of Pokémon on my app's homepage by fetching it from the API.

export class HomeComponent implements OnInit {

    pokemon$: ReplaySubject<ResourceList> = new ReplaySubject<ResourceList>();

    constructor(private pokedexService: PokedexService, private state: TransferState) { }

    ngOnInit() {
        if (this.state.hasKey(STATE_KEY_POKEMON)) {
            this.pokemon$.next(this.state.get(STATE_KEY_POKEMON, {} as ResourceList));
        }
        else {
            this.pokedexService.getResourceByCategory(ResourceCategory.POKEMON)
                .subscribe((resourceList: ResourceList) => {
                    this.pokemon$.next(resourceList);
                    this.state.set(STATE_KEY_POKEMON, resourceList.results);
                });
        }
    }
}

This functionality works smoothly when rendering pages via the client. However, issues arise when attempting to pre-render the application, causing build processes to hang. Despite confirming that the API call returns a 200 status, the log displays a similar output:

npm run build:prerender

> Initiating build process C:\Users\thijs\Development\pokedex universal\angular-universal-pokedex
> npm run build:client-and-server-bundles && npm run compile:server && npm run generate:prerender


> Initiate build for client and server bundles C:\Users\thijs\Development\pokedex universal\angular-universal-pokedex
> ng build --prod && ng run ng-universal-demo:server:production


Date: 2018-09-22T16:47:41.687Z
Hash: c49708f1ccb7e73e327a
Time: 8181ms
chunk {0} runtime.6afe30102d8fe7337431.js (runtime) 1.05 kB [entry] [rendered]
chunk {1} styles.34c57ab7888ec1573f9c.css (styles) 0 bytes [initial] [rendered]
chunk {2} polyfills.c174e4dc122f769bd68b.js (polyfills) 64.3 kB [initial] [rendered]
chunk {3} main.19481e4ceb7a5808fe78.js (main) 312 kB [initial] [rendered]

Date: 2018-09-22T16:47:50.816Z
Hash: ee7e30e1f9c277bb5cbf
Time: 5739ms
chunk {main} main.js (main) 38.2 kB [entry] [rendered]

> Compiling server code C:\Users\thijs\Development\pokedex universal\angular-universal-pokedex
> tsc -p server.tsconfig.json


> Generating pre-render content C:\Users\thijs\Development\pokedex universal\angular-universal-pokedex
> cd dist && node prerender

To successfully complete the pre-rendering build process, I had to eliminate the web request altogether. There seems to be some background process hindering progress even after switching to an Observable Promise. What critical aspect am I overlooking?

Check out my project on GitHub.

Answer №1

If you're struggling with delays, here's some advice that may be helpful:

Just as we discussed waiting for macrotasks to finish in the previous section, it's important to note that the platform won't wait for microtasks to complete before rendering. In Angular Universal, we have modified the Angular HTTP client to act as a macrotask so that any necessary HTTP requests are completed before rendering. However, this approach might not be suitable for all microtasks, so it's best to use your discretion on how to proceed. You can examine the code reference on how Universal transforms a task into a macrotask or consider changing the server behavior of specific tasks.

Essentially, if your http requests or websocket connections (such as those used by Firebase in angular-firebase) take too long, the prerendering process may stall and not finish. Additionally, when I encountered this issue, there were no error messages in the terminal, making debugging quite challenging.

I recommend the following steps:

  • For client-side rendering (CSR), only use websocket connections and wrap them within an if statement.
  • For server-side rendering (SSR) or static prerendering, utilize REST API endpoints and ensure you avoid timeout errors.

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

Tips for incorporating conditional types into function parameters based on existing input

The title might be confusing, so allow me to clarify. My Objective I am referring to the code snippet below. I aim to specify the route property based on the types property as either a string or a function that returns a string. The Code Let's b ...

What exactly is the data type of setInterval in TypeScript?

If I want to define the type of a variable that will be used with setInterval in the following code snippet: this.autoSaveInterval = setInterval(function(){ if(this.car.id){ this.save(); } else{ this.create(); } ...

Introducing a delay in an observable causes incomplete data to be received in Angular using rxjs

Currently, I am facing an issue in my code where I am trying to introduce a delay using timer(500). However, the problem is that it is only returning partial data. Instead of the expected 17 fields, it is only returning 2 fields. Below is my code snippet f ...

The NestJS error code TS7016 was triggered due to the absence of a declaration file for the 'rxjs' module

TS7016: An error occurred while trying to locate a declaration file for the module 'rxjs'. The file 'C:/Path/to/project/node_modules/rxjs/dist/cjs/index.js' is implicitly set to type 'any'. You can try running npm i --save-dev ...

Module '../../third_party/github.com/chalk/supports-color' not found in the directory

Within my tutoring-frontend-main project folder There is a file named package.json { "name": "app-frontend", "version": "0.0.0", "license": "MIT", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build --prod", "test": "n ...

The failure to import a node module in next.js with typescript

I'm currently working on integrating a package called bcrypt into my project. I have successfully installed it using npm install bcrypt. Although the package is visible in the node_modules folder, I am encountering an error when trying to import it i ...

How can I customize the styling of Angular Material Datepicker?

I am currently incorporating the Angular Material Datepicker into various parts of my application. One particularly important usage is a legacy one that must remain untouched for the proper functioning of the application. This legacy Datepicker is extensiv ...

Combining meanings within a geometric interface

When setting up my routes, I like to include an additional field in the configuration. This is how I do it: app.config([ '$routeProvider', ($routeProvider: ng.route.IRouteProvider) => { $routeProvider ...

When utilizing typescript to develop a node module and importing it as a dependency, an issue may arise with a Duplicate identifier error (TS2300)

After creating a project called data_model with essential classes, I built a comprehensive gulpfile.js. This file not only compiles .ts to .js but also generates a unified .d.ts file named data_model.d.ts, which exports symbols and is placed at the root of ...

The @Input decorator in Angular 2/4 is designed to only transfer fundamental values and not collections or complex data

I have encountered an issue while attempting to use @Input with a list of objects, where the @Input variable ends up being undefined. What is functioning properly can be seen in home.component.html: <p> <it-easy [mycount]="countItem" (result ...

The AuthGuard (Guard decorator) is unable to resolve its dependencies according to Nest

My AuthGuard is responsible for checking the JWT token in controllers. I am trying to use this Guard in controllers to verify authentication, but I encountered the following error: Nest cannot resolve dependencies of the AuthGuard (?, +). Please ensur ...

Resolving ES6 type conflicts while compiling TypeScript to Node.js

I seem to be facing some challenges with the TypeScript 2 type system when working with Node.js. Let me explain the situation: I am compiling a small Node.js Express server written in TypeScript to plain ES5 for running under Node 6.10.0 (target: ES5 in ...

Error encountered during installation of Nativescript Post Install Script

While I am comfortable running one of our current projects with Nativescript, I encountered an error when attempting to install it on a new project using the following command: sudo ng new --collection=@nativescript/schematics the-juice-box --shared The ...

Error: Idle provider not found in the promise

Currently, I am integrating ng2-idle into an AngularJS 2 application. After successfully including the ng2-idle package in the node_modules directory of my project, I attempted to import it into one of my components as shown below: Dashboard.component.ts: ...

What is the best method for dividing a user interface into several arrays of keys, each grouped by type?

Given a simple structure: structure IPerson { firstName: string; lastName: string; age: number; city: string; favoriteNumber: number; isMarried: boolean; hasDriverLicense: boolean; } How do I create arrays containing keys grouped by data typ ...

How can I find the "types" specific to modules within the "firebase" library?

I have a question that applies to various scenarios, with Firebase serving as an example. When working on my react project, I find myself wanting to import firebase from "@firebase/app", which is logical. However, if I want the const locationRef ...

The battle of Any, Generic Type, and Unknown in Typescript

Is it advisable to replace the type any with Generic Types? I understand that using type any is generally discouraged as it removes type checking in TypeScript, making it unsafe. So what is a better alternative - using unknown or generic types? For examp ...

Is there a distinction between Entity[] and array<Entity> in TypeScript?

Everything in the title, for example people: Person[]; people: Array<Person>; What sets them apart? Is there a preferred approach? Note: I couldn't find any guidance on this and I've encountered both in code. ...

How can I showcase a different component within another *ngFor loop?

I am currently working on a table in HTML that displays product information. Here is the code snippet for it: <form [formGroup]="myform" (ngSubmit)="submit()" > <tbody> <tr class="group" *ngFor="let item of products;"&g ...

Creating personalized properties for a Leaflet marker using Typescript

Is there a way to add a unique custom property to each marker on the map? When attempting the code below, an error is triggered: The error "Property 'myCustomID' does not exist on type '(latlng: LatLngExpression, options?: MarkerOptions) ...