2

I'm working on a small web app based on the angular universal starter and the pokeapi. Since a lot of the data that I want to show doesn't actually change, I want to use pre-rendered pages to reduce the number of requests made to the API and to improve performance. For my example I have put a list of pokemons on the home page of my app which I retrieve 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 works fine when I have the client render the page. However, when I attempt to pre-render the app, the build process hangs. Since I'm running a local instance of the API, I can see that a request was made and it returned with a 200 status. The build log looks like this:

npm run build:prerender

> [email protected] build:prerender C:\Users\thijs\Development\pokedex universal\angular-universal-pokedex
> npm run build:client-and-server-bundles && npm run compile:server && npm run generate:prerender


> [email protected] build: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]

> [email protected] compile:server C:\Users\thijs\Development\pokedex universal\angular-universal-pokedex
> tsc -p server.tsconfig.json


> [email protected] generate:prerender C:\Users\thijs\Development\pokedex universal\angular-universal-pokedex
> cd dist && node prerender

The only way I get the pre-rendering build to complete is by removing the web request. I'm thinking there must still be something running in the background. I tried switching my Observable to a Promise, but that did not change anything. What am I missing?

You can find my project on GitHub.

2
  • Have you found a solution? Commented Sep 23, 2020 at 20:40
  • try checking youtube.com/… Commented Apr 17, 2022 at 3:31

1 Answer 1

2

A bit late, but this might help if someone struggles:

Similarly to the above section on waiting for macrotasks to complete, the flip-side is that the platform will not wait for microtasks to complete before finishing the render. In Angular Universal, we have patched the Angular HTTP client to turn it into a macrotask, to ensure that any needed HTTP requests complete for a given render. However, this type of patch may not be appropriate for all microtasks, and so it is recommended you use your best judgment on how to proceed. You can look at the code reference for how Universal wraps a task to turn it into a macrotask, or you can simply opt to change the server behavior of the given tasks.

Basically if your http requests take too long the prerender hangs and won't finish. Same goes for the websocket connections(firebase uses WS in angular-firebase). Plus when I had this issue there was no error output in terminal, which made debugging really hard. I'd sugest following:

  • WS connections only on CSR, wrap them asswell in an if statement
  • for SSR, or static prerender use rest api endpoints and make sure you don't get any timeout errors.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.