Angular has had a built-in way to wait on your functions to load, and you didn't know about it!
In the past...
You needed to import the hidden function...
import{ɵPendingTasksasPendingTasks}from'@angular/core';
Notice the greek letter that you wouldn't normally find with autocomplete.
Today
It is experimental, but you will soon be able to just importPendingTasks
.
import{ExperimentalPendingTasksasPendingTasks}from'@angular/core';
Setup
I use myuseAsyncTransferState
function for hydration. This ensures an async call, a fetch in this case, only runs once, and on the server.
exportconstuseAsyncTransferState=async<T>(name:string,fn:()=>T)=>{conststate=inject(TransferState);constkey=makeStateKey<T>(name);constcache=state.get(key,null);if(cache){returncache;}constdata=awaitfn()asT;state.set(key,data);returndata;};
Token
We need reusable tokens for theREQUEST
object.
// request.token.tsimport{InjectionToken}from"@angular/core";importtype{Request,Response}from'express';exportconstREQUEST=newInjectionToken<Request>('REQUEST');exportconstRESPONSE=newInjectionToken<Response>('RESPONSE');
We must pass the request object as a provider in our render function.
// main.server.tsexportdefaultasyncfunctionrender(url:string,document:string,{req,res}:{req:Request;res:Response}){consthtml=awaitrenderApplication(bootstrap,{document,url,platformProviders:[{provide:REQUEST,useValue:req},{provide:RESPONSE,useValue:res},],});returnhtml;}
Angular is currently in the process ofadding all of these features, and potentially endpoints!!!!! 😀 😀 😀 🗼 🎆
Fetch Something
Because endpoints are not currently there, I am testing this with Analog. Here is ahello
endpoint that takes 5 seconds to load.
import{defineEventHandler}from'h3';exportdefaultdefineEventHandler(async()=>{constx=newPromise((resolve)=>setTimeout(()=>{resolve({message:"loaded from the server after 5 seconds!"});},5000));returnawaitx;});
Test Component
Here we use therequest
in order to get the host URL. Then we useuseAsyncTransferState
to ensure things only run on the server, and only once. Finally, we usependingTasks
to ensure the component is not fully rendered until the async completes.
import{AsyncPipe}from'@angular/common';import{Component,ExperimentalPendingTasksasPendingTasks,inject,isDevMode}from'@angular/core';import{REQUEST}from'@lib/request.token';import{useAsyncTransferState}from'@lib/utils';@Component({selector:'app-home',standalone:true,imports:[AsyncPipe],template:` <div> <p>{{ data | async }}</p> </div> `})exportdefaultclassHomeComponent{privatependingTasks=inject(PendingTasks);protectedreadonlyrequest=inject(REQUEST);data=this.getData();// fetch data, will only run on serverprivateasync_getData(){constschema=isDevMode()?'http://':'https://';consthost=this.request.headers.host;consturl=schema+host+'/api/hello';constr=awaitfetch(url,{headers:{'Content-Type':'application/json',}});constx=awaitr.json();returnx.message;}// fetch data with pending task and transfer stateasyncgetData(){consttaskCleanup=this.pendingTasks.add();constr=awaituseAsyncTransferState('pending',async()=>awaitthis._getData());taskCleanup();returnr;}}
Pending Task
Pending Task is very simple.
// create a new taskconsttaskCleanup=this.pendingTasks.add();// do something asyncconstr=awaitfn();// let Angular know it can rendertaskCleanup();
Thats it! Bingo Shabongo!
Repo:GitHub
Demo:Vercel Edge - Takes 5s to load!
Should you use this?
Nope! Seriously, don't use this.
After going down the rabbit hole for years on Angular async rendering (read the old posts in this chain), it is definitely best practice to put ALL async functions in aresolver
. The resolver MUST load before a component, which is a much better development environment. The only exception would be@defer
IMHO.
However, there are some edge cases where it makes sense for your app. The is particularly evident when you don't want to rewrite your whole application to use resolvers. Either way, you need to be aware of your options!
J
Top comments(2)

Hello, All this look alien to me because its my first time getting into server side rendering. How easy is this SSR of Angular when it comes deployment? There are no many articles or guides on how to do this?
How effective is SSR of Angular so far when it comes to SEO?

- LocationLouisiana
- EducationLSU, Oregon State, Middlebury
- Joined
Look into Analog. Angular by itself is terrible with SSR deployment. -analogjs.org/
For further actions, you may consider blocking this person and/orreporting abuse