Concorde decorator — @post. Sends the value of a publisher as the body of a POST request and stores the response in an ApiResult<T> property. Pass an Endpoint and a DataProviderKey for the body; the request runs on connect and a Doc ID: docs/decorators/post. Keywords: Concorde, supersoniks, docs/decorators/post, post, @post, decorator, POST, ApiResult, undefined, request, response, result, POST /docs-mock-api/api/register, send(component), Promise | undefined>. URL: https://concorde.supersoniks.org/docs/decorators/post.
@post
Sends the value of a publisher as the body of a POST request and stores the response in an ApiResult<T> property. Pass an Endpoint and a DataProviderKey for the body; the request runs on connect and again whenever the body changes. @put and @patch work the same way.
Import
import { post, type ApiResult } from "@supersoniks/concorde/decorators";
import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
import { Endpoint } from "@supersoniks/concorde/utils/endpoint";
type SignUp = { email: string; password: string };
type CrewMember = { id: number; email: string };
const signUpKey = new DataProviderKey<SignUp>("crewSignUp");
@post(new Endpoint<CrewMember>("api/register"), signUpKey)
@state()
payload?: ApiResult<CrewMember>;
Basic usage
The property is undefined until a response arrives, then holds request · response · the typed result. Each body mutation sends a new request; mutations in the same frame are coalesced into one. The demo posts to the local mock POST /docs-mock-api/api/register.
<docs-demo-sources for="demo-api-post"></docs-demo-sources>
<demo-api-post></demo-api-post>
Method form
On a method, the decorator calls it with the full ApiResult<T> after each request instead of assigning a property.
<docs-demo-sources for="demo-api-post-method"></docs-demo-sources>
<demo-api-post-method></demo-api-post-method>
Sending again
Keep the decorator in a constant to call send(component). It reads the current body and returns a Promise<ApiResult<T> | undefined> resolved once the request completes. Use it for "Save" or "Retry" buttons.
const signUp = post(new Endpoint<CrewMember>("api/register"), signUpKey);
@signUp
@state()
payload?: ApiResult<CrewMember>;
async retry() {
const payload = await signUp.send(this);
console.log(payload?.result?.id);
}
The send method decorator does the same around a method. It runs after the method by default (waiting for a returned Promise); { when: "before" } sends first.
import { send } from "@supersoniks/concorde/decorators";
@send(signUp)
async confirmCheckIn() {
// Validate the check-in form, then the POST is sent.
}
Manual trigger
Set autoPostOnBodyMutation: false when the body is edited field by field (a check-in form) and the request must only go out on send() or triggerKey. A triggerKey publisher lets another component resend: calling invalidate() on it sends the current body.
const submitKey = new DataProviderKey<number>("checkInSubmit");
@post(checkInEndpoint, checkInKey, {
autoPostOnBodyMutation: false,
triggerKey: submitKey,
})
@state()
payload?: ApiResult<CheckIn>;
// Anywhere: dp(submitKey).invalidate();
By default (skipIfBodyMissing: true) nothing is sent while the body is null or undefined. refetchEveryMs repeats the request at a fixed interval after each response; use it only when repeating the operation is safe.
API configuration
Without a configuration key, serviceURL and credentials come from the HTML scope, as with @get. Pass a DataProviderKey<APIConfiguration> as third argument to read them from a publisher; options then move to the fourth argument. See API configuration.
@post(signUpEndpoint, signUpKey, apiConfigurationKey, { skipIfBodyMissing: false })
Dynamic path
Placeholders in the endpoint (${flight}) are read from the host component; changing the property sends the same body to the new URL. See Dynamic paths.
<docs-demo-sources for="demo-api-post-dynamic"></docs-demo-sources>
<demo-api-post-dynamic></demo-api-post-dynamic>
API reference
post(endpoint, bodyKey, configurationKey?, options?) returns a decorator for a property or a method, with a send(component) method.
| Argument | Type | Description |
|---|---|---|
endpoint |
Endpoint<T> |
Path and response type. Supports ${prop} placeholders |
bodyKey |
DataProviderKey<B> |
Publisher read as request body |
configurationKey |
DataProviderKey<APIConfiguration> (optional) |
API configuration publisher. Default: HTML scope |
options.autoPostOnBodyMutation |
boolean (default true) |
Send on connect and after each body mutation |
options.skipIfBodyMissing |
boolean (default true) |
Skip while the body is null or undefined |
options.triggerKey |
DataProviderKey<unknown> |
Publisher whose invalidate() resends |
options.refetchEveryMs |
number (default 0, off) |
Resend interval in ms after each response |
options.skipEmptyPlaceholder |
boolean (default false) |
Treat a placeholder resolved to "" as not ready |
send(handle, { when }) |
"after" (default) or "before" |
Method decorator sending after or before the method |