On this page
Overview
Data fetching in Analog builds on top of concepts in Angular, such as using HttpClient for making API requests.
To call typed server-side code directly instead of writing an API route and a client request for it, see Server Functions.
Using HttpClient
Using HttpClient is the recommended way to make API requests for internal and external endpoints. The context for the request is provided by the provideServerContext function for any request that uses HttpClient and begins with a /.
Server Request Context
On the server, use the provideServerContext function from the Analog router in the main.server.ts.
// Analog server context
if (import.meta.env.PROD) {
enableProdMode();
}
export function bootstrap() {
return bootstrapApplication(AppComponent, config);
}
export default async function render(
url: string,
document: string,
serverContext: ServerContext,
) {
const html = await renderApplication(bootstrap, {
document,
url,
platformProviders: [provideServerContext(serverContext)],
});
return html;
}
This provides the Request and Response, and Base URL from the server and registers them as providers that can be injected and used.
Injection Functions
class MyService {
request = injectRequest(); // <- Server Request Object
response = injectResponse(); // <- Server Response Object
baseUrl = injectBaseURL(); // <-- Server Base URL
}
Request Context Interceptor
Analog provides requestContextInterceptor for the HttpClient that handles transforming any request to URL beginning with a / to a full URL request on the server, client, and during prerendering. During SSR and prerendering, responses are stored in TransferState so the client reuses them instead of fetching the data again.
provideFileRouter() registers the interceptor automatically, so a plain provideHttpClient() is all you need.
export const appConfig: ApplicationConfig = {
providers: [
provideFileRouter(withNavigationErrorHandler(console.error)),
provideHttpClient(withFetch()),
provideClientHydration(),
],
};
The interceptor runs after any interceptors you register with
withInterceptors(), so you don't need to add it yourself.
Making Requests
In your component/service, use HttpClient along with API routes with providing a full URL.
An example API route that fetches todos.
// src/server/routes/api/v1/todos.ts -> /api/v1/todos
import { defineEventHandler } from 'h3';
export default defineEventHandler(async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/todos');
const todos = await response.json();
return todos;
});
An example service that fetches todos from the API endpoint.
// todos.service.ts
@Injectable({
providedIn: 'root',
})
export class TodosService {
http = inject(HttpClient);
getAll() {
return this.http.get<Todo[]>('/api/v1/todos');
}
getData() {
return this.http.get<Todo[]>('/assets/data.json');
}
}
Data requests also use Angular's TransferState to store any requests made during Server-Side Rendering, and are transferred to prevent an additional request during the initial client-side hydration.