Concorde decorator — @post. @post sends the contents of a publisher and stores the response in an Doc ID: docs/_decorators/post. Keywords: Concorde, supersoniks, docs/_decorators/post, post, @post, decorator, ApiResult, undefined, Endpoint, DataProviderKey,
The current body is read from , send(component),
, returns a ,
Use . URL: https://concorde.supersoniks.org/crawl/docs/_decorators/post.html.
@post
@post sends the contents of a publisher and stores the response in an
optional ApiResult<T> property. The property is undefined until a result
is available.
Minimal usage
Pass an Endpoint<T> and a DataProviderKey<B> for the request body.
const userBodyKey = new DataProviderKey<CreateUser>("users.form");
const createUser = post(new Endpoint<User>("users"), userBodyKey);
@createUser
@state()
payload?: ApiResult<User>;
The same decorator adapts to a method and receives the complete payload:
@post(new Endpoint<User>("users"), userBodyKey)
handleCreate(payload?: ApiResult<User>) {
if (payload?.response?.ok) console.log(payload.result);
}
The current body is read from userBodyKey. By default, the POST is sent when
the component connects and after each body mutation. Mutations in the same
frame are coalesced into one request.
API configuration is read from the HTML scope, as with @get.
Sending the POST again
From the component
Keep the decorator to access send(component). The body is read again when the
operation runs.
async saveAgain() {
const payload = await createUser.send(this);
console.log(payload?.result);
}
send() returns a Promise<ApiResult<T> | undefined> that resolves after the
operation completes. It is useful for “Save” or “Retry” buttons and can repeat
an operation with side effects.
From a method decorator
The send action can decorate a local method. It runs after the method by default, waits for an eventual Promise to resolve, and the decorated method call waits for the send to complete:
import { send } from "@supersoniks/concorde/decorators";
@send(createUser)
async save() {
// Prepare local state or validate the form.
}
Use { when: "before" } when the send must complete before the method runs:
@send(createUser, { when: "before" })
saveBefore() {
// The POST has completed before this method runs.
}
The method decorator adds an explicit send. If the method also mutates the body
publisher, set autoPostOnBodyMutation: false when the decorated method must
be the only trigger.
Options (PostOptions)
Options are the third argument, or the fourth argument when a configuration key is provided.
autoPostOnBodyMutation: send after a body mutation (default:true). Set it tofalseto usesend().skipIfBodyMissing: skip when the body isnullorundefined(default:true).refetchEveryMs: repeat the POST at this interval. Use it only when repeating the operation is intended.skipEmptyPlaceholder: block the request when a${...}placeholder is"".triggerKey: a publisher whoseinvalidate()sends the POST again.
With a configuration key:
@post(endpoint, userBodyKey, apiConfigurationKey)
See Dynamic path placeholders for dynamic path details.
When the POST is sent
- when the component connects and the body and configuration are available;
- after a body mutation, unless
autoPostOnBodyMutation: false; - when a property used in
${...}changes; - when a configuration publisher changes;
- when the
triggerKeypublisher is invalidated; - when
send()is called; - after each response when
refetchEveryMsis set.
Import
import { post, type ApiResult } from "@supersoniks/concorde/decorators";
import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
import { Endpoint } from "@supersoniks/concorde/utils/endpoint";
Demos
<docs-demo-sources for="demo-api-post"></docs-demo-sources>
<demo-api-post></demo-api-post>
<docs-demo-sources for="demo-api-post-method"></docs-demo-sources>
<demo-api-post-method></demo-api-post-method>
<docs-demo-sources for="demo-api-post-dynamic"></docs-demo-sources>
<demo-api-post-dynamic></demo-api-post-dynamic>
See @put and @patch: they use the same model with a different HTTP method.
Advanced
External invalidation is currently available through triggerKey; it is kept
out of the main usage examples.