Description
Thanks for fixing the Angular HttpClient call body placement. I tested this with orval@8.10.0 against our generated Angular client and it does fix the main runtime issue: this.http.post/put/patch(...) now receives the request body as the positional body argument before the options object.
There still seems to be a related signature/order issue for operations with:
- a request body,
- route/path parameters,
- multiple response content types / accept overloads.
Example generated output:
postApiV1ReservationConfirmationsByTokenConfirmationToken(
confirmationToken: string,
accept: 'application/json',
nullConfirmReservationResourceRequest?: null | ConfirmReservationResourceRequest,
options?: HttpClientOptions
): Observable<ReservationConfirmationResultResponse>;
The actual HttpClient call is now correct:
return this.http.post<ReservationConfirmationResultResponse>(
`/api/v1/reservation-confirmations/by-token/${confirmationToken}`,
nullConfirmReservationResourceRequest,
{
...options,
responseType: 'json',
headers,
},
);
But the generated public method signature still places accept before the request body. This is inconsistent with the rest of the generated body-verb methods and with the expected call shape where the request body remains the second user-facing argument after path params
postApiV1ReservationConfirmationsByTokenConfirmationToken(
confirmationToken: string,
nullConfirmReservationResourceRequest: null | ConfirmReservationResourceRequest | undefined,
accept: 'application/json',
options?: HttpClientOptions
): Observable<ReservationConfirmationResultResponse>;
This matters because existing callers naturally pass the body as the second argument. With the current generated overload order, TypeScript callers get an API break, and JS/any callers can accidentally pass a body object into accept, which then reaches accept.includes(...) and can throw at runtime.
So #3335 appears to fix the HttpClient call expression, but not the overload/implementation parameter order for this multi-content Angular case.
Output client
angular
Configuration (orval.config)
import { defineConfig } from 'orval';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
const configDirectory = dirname(fileURLToPath(import.meta.url));
const workspaceRoot = resolve(configDirectory, '../../..');
const openApiDocumentPath = resolve(workspaceRoot, 'dist/apps/api/openapi/api.json');
const generatedRoot = resolve(configDirectory, 'src/generated');
export default defineConfig({
leveraApi: {
input: {
target: openApiDocumentPath,
},
output: {
mode: 'tags-split',
target: resolve(generatedRoot, 'http-client/index.ts'),
schemas: resolve(generatedRoot, 'models'),
client: 'angular',
override: {
angular: {
retrievalClient: 'both',
provideIn: 'root',
},
zod: {
generate: {
body: true,
response: true,
query: true,
param: true,
header: true,
},
},
},
clean: true,
},
},
leveraApiZod: {
input: {
target: openApiDocumentPath,
},
output: {
mode: 'single',
target: resolve(generatedRoot, 'schemas/index.ts'),
client: 'zod',
clean: false,
},
},
});
Environment
Run the command above and paste the output here.
System:
OS: macOS 26.3.1
CPU: (14) arm64 Apple M4 Pro
Memory: 967.80 MB / 48.00 GB
Shell: 5.9 - /bin/zsh
npmPackages:
@angular/common: ~21.2.9 => 21.2.9
@angular/core: ~21.2.9 => 21.2.9
orval: 8.10.0
zod: ^4.1.11 => 4.3.6
Expected behavior
No response
Actual behavior
No response
OpenAPI document (minimal, if applicable)
openapi: 3.0.3
info:
title: Demo
version: 0.0.0
paths: {}
Additional context
No response
Description
Thanks for fixing the Angular
HttpClientcall body placement. I tested this withorval@8.10.0against our generated Angular client and it does fix the main runtime issue:this.http.post/put/patch(...)now receives the request body as the positional body argument before the options object.There still seems to be a related signature/order issue for operations with:
Example generated output:
The actual HttpClient call is now correct:
But the generated public method signature still places accept before the request body. This is inconsistent with the rest of the generated body-verb methods and with the expected call shape where the request body remains the second user-facing argument after path params
This matters because existing callers naturally pass the body as the second argument. With the current generated overload order, TypeScript callers get an API break, and JS/any callers can accidentally pass a body object into accept, which then reaches accept.includes(...) and can throw at runtime.
So #3335 appears to fix the HttpClient call expression, but not the overload/implementation parameter order for this multi-content Angular case.
Output client
angular
Configuration (orval.config)
import { defineConfig } from 'orval';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
const configDirectory = dirname(fileURLToPath(import.meta.url));
const workspaceRoot = resolve(configDirectory, '../../..');
const openApiDocumentPath = resolve(workspaceRoot, 'dist/apps/api/openapi/api.json');
const generatedRoot = resolve(configDirectory, 'src/generated');
export default defineConfig({
leveraApi: {
input: {
target: openApiDocumentPath,
},
output: {
mode: 'tags-split',
target: resolve(generatedRoot, 'http-client/index.ts'),
schemas: resolve(generatedRoot, 'models'),
client: 'angular',
override: {
angular: {
retrievalClient: 'both',
provideIn: 'root',
},
zod: {
generate: {
body: true,
response: true,
query: true,
param: true,
header: true,
},
},
},
clean: true,
},
},
leveraApiZod: {
input: {
target: openApiDocumentPath,
},
output: {
mode: 'single',
target: resolve(generatedRoot, 'schemas/index.ts'),
client: 'zod',
clean: false,
},
},
});
Environment
Run the command above and paste the output here.
System:
OS: macOS 26.3.1
CPU: (14) arm64 Apple M4 Pro
Memory: 967.80 MB / 48.00 GB
Shell: 5.9 - /bin/zsh
npmPackages:
@angular/common: ~21.2.9 => 21.2.9
@angular/core: ~21.2.9 => 21.2.9
orval: 8.10.0
zod: ^4.1.11 => 4.3.6
Expected behavior
No response
Actual behavior
No response
OpenAPI document (minimal, if applicable)
Additional context
No response