Concorde documentation · same URL (interactive) · llms.txt

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&lt;SignUp&gt;("crewSignUp");

@post(new Endpoint&lt;CrewMember&gt;("api/register"), signUpKey)
@state()
payload?: ApiResult&lt;CrewMember&gt;;

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&lt;CrewMember&gt;("api/register"), signUpKey);

@signUp
@state()
payload?: ApiResult&lt;CrewMember&gt;;

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&lt;number&gt;("checkInSubmit");

@post(checkInEndpoint, checkInKey, {
  autoPostOnBodyMutation: false,
  triggerKey: submitKey,
})
@state()
payload?: ApiResult&lt;CheckIn&gt;;

// 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