> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aftersell.com/llms.txt
> Use this file to discover all available pages before exploring further.

# アクション

> カートの読み取りと変更のための Aftersell Cart SDK の全アクション: 開閉、追加、削除、数量更新、バリアントの交換、状態の読み取り、金額のフォーマット。

アクションは**カートを読み取り、変更します**。`window.aftersell.cart.actions` の下にあります。

<Note>
  アクションは、`ready()` の中または[イベント](/ja/aftersell/cart/sdk-events)ハンドラの中で、**カートの準備が整ってから**実行してください。
</Note>

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.ready().then(() => {
  const state = window.aftersell.cart.actions.getCart();
  console.log(state.itemCount, 'items');
});
```

<Note>
  **カートの読み込み前、アクションはスタブです。** それぞれがアクション名を含むコンソール警告（例: `cart.actions.addItem() called before the cart loaded`）を出力し、何もしません。非同期アクションは Promise を解決するため、`.then()` チェーンは例外を投げずに通常どおり実行されます。`getCart()` は `null` を返し、`formatMoney()` は空文字列を返します。

  早く呼びすぎても何も壊れませんが、何も起こりません。アクションが何もしていないように見えるときは、コンソールでその警告を確認してください。
</Note>

<div id="every-action">
  ## すべてのアクション
</div>

| アクション                                                    | シグネチャ                                | 戻り値                     | 動作                    |
| -------------------------------------------------------- | ------------------------------------ | ----------------------- | --------------------- |
| [`open`](#open-and-close)                                | `open()`                             | なし                      | ドロワーを開きます。            |
| [`close`](#open-and-close)                               | `close()`                            | なし                      | ドロワーを閉じます。            |
| [`getCart`](#getcart)                                    | `getCart()`                          | `AftersellCart \| null` | 現在のカートを読み取ります。        |
| [`formatMoney`](#formatmoneycents)                       | `formatMoney(cents)`                 | `string`                | 金額を表示用にフォーマットします。     |
| [`addItem`](#additemvariantid-quantity)                  | `addItem(variantId, quantity?)`      | `Promise`               | バリアントを追加します。          |
| [`removeItem`](#removeitemkey)                           | `removeItem(key)`                    | `Promise`               | ラインを削除します。            |
| [`updateItemQuantity`](#updateitemquantitykey-quantity)  | `updateItemQuantity(key, quantity)`  | `Promise`               | ラインの数量を設定します。         |
| [`replaceLineVariant`](#replacelinevariantkey-variantid) | `replaceLineVariant(key, variantId)` | `Promise`               | ラインのバリアントを交換します。      |
| [`refresh`](#refresh)                                    | `refresh()`                          | `Promise`               | Shopify からカートを再取得します。 |
| [`visualRefresh`](#visualrefresh)                        | `visualRefresh()`                    | なし                      | 再取得せずに再描画します。         |

<Warning>
  `cart_updated` ハンドラからアクションを呼ぶとループする可能性があります。まず[2 つのルール](/ja/aftersell/cart/sdk-events#the-two-rules)を読んでください。
</Warning>

***

<div id="drawer">
  ## ドロワー
</div>

<div id="open-and-close">
  ### open と close
</div>

カートドロワーを開閉します。どちらも同期的で、引数を取りません。

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Open the drawer from your own cart link.
document.querySelector('#my-cart-link').addEventListener('click', (event) => {
  event.preventDefault();
  window.aftersell.cart.actions.open();
});
```

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Close it after the shopper does something in a custom block.
window.aftersell.cart.actions.close();
```

***

<div id="reading">
  ## 読み取り
</div>

<div id="getcart">
  ### getCart()
</div>

現在の[カートオブジェクト](/ja/aftersell/cart/sdk-cart-object)を返します。読み込み前は `null` を返します。結果は**コピー**なので、書き換えても実際のカートは変わりません。

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.ready().then(() => {
  const state = window.aftersell.cart.actions.getCart();
  if (!state) return; // the initial load failed

  console.log(state.itemCount, 'items,', state.items.length, 'lines');
  console.log('Total:', window.aftersell.cart.actions.formatMoney(state.totalPrice));
});
```

スナップショットなので、結果を保持し続けず、最新のデータが必要になるたびに読み直してください。イベントハンドラの中では、すでにペイロードとして最新のカートを受け取っているため、そこで `getCart()` を呼ぶ必要はありません。

<div id="formatmoneycents">
  ### formatMoney(cents)
</div>

ストアの金額フォーマットを使って、最小通貨単位の金額をフォーマットします。SDK 内のすべての価格はセント単位なので、これが表示可能な形に変換する方法です。

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.actions.formatMoney(5779);  // "$57.79"
window.aftersell.cart.actions.formatMoney(0);     // "$0.00"
```

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Show the cart total in your own header element.
window.aftersell.cart.events.on('cart_updated', (state) => {
  document.querySelector('#header-total').textContent =
    window.aftersell.cart.actions.formatMoney(state.totalPrice);
});
```

フォーマットは [`configure({ money_format })`](/ja/aftersell/cart/sdk-configure#money_format) で上書きできます。

***

<div id="changing-the-cart">
  ## カートの変更
</div>

<Note>
  アイテム系のアクションは、バリアント ID ではなく Shopify の **`key`** でラインを識別します。カートは同じバリアントを異なるプロパティで複数のラインに保持できるためです。`getCart().items[n].key` から読み取ってください。
</Note>

<div id="additemvariantid-quantity">
  ### addItem(variantId, quantity?)
</div>

バリアントをカートに追加します。`quantity` のデフォルトは `1` です。カートが確定した時点で解決されます。

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Add one, then show the shopper.
window.aftersell.cart.actions.addItem(41720671830082).then(() => {
  window.aftersell.cart.actions.open();
});
```

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Add a specific quantity.
window.aftersell.cart.actions.addItem(41720671830082, 3);
```

すでにカートに入っているバリアントを追加すると、既存のラインにラインアイテムプロパティがない限り、2 つ目のラインが作られるのではなく、そのラインの数量が増えます。プロパティを持つラインは別のラインとして扱われるため、新しいラインが作られます。

<div id="removeitemkey">
  ### removeItem(key)
</div>

ラインを完全に削除します。

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Remove any free line from the cart.
const gift = window.aftersell.cart.actions
  .getCart()
  .items.find((line) => line.finalLinePrice === 0);
if (gift) window.aftersell.cart.actions.removeItem(gift.key);
```

<div id="updateitemquantitykey-quantity">
  ### updateItemQuantity(key, quantity)
</div>

ラインの数量を設定します。`0` を渡すとラインが削除されます。

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const line = window.aftersell.cart.actions.getCart().items[0];
if (line) window.aftersell.cart.actions.updateItemQuantity(line.key, 3);
```

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Cap a line at one unit.
window.aftersell.cart.events.on('cart_updated', (state) => {
  state.items.forEach((line) => {
    if (line.variantId === LIMITED_VARIANT_ID && line.quantity > 1) {
      window.aftersell.cart.actions.updateItemQuantity(line.key, 1);
    }
  });
});
```

2 つ目の例は、2 回目のパスでは `> 1` のチェックが false になるため、`cart_updated` から実行しても安全です。[2 つのルール](/ja/aftersell/cart/sdk-events#the-two-rules)を参照してください。

<div id="replacelinevariantkey-variantid">
  ### replaceLineVariant(key, variantId)
</div>

数量とプロパティを保持したまま、ラインのバリアントを交換します。カート内のサイズやフレーバーの切り替えに便利です。

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const line = window.aftersell.cart.actions.getCart().items[0];
window.aftersell.cart.actions.replaceLineVariant(line.key, 41720671862850);
```

<Warning>
  交換すると、ラインの**販売プランはリセットされます**。プランを再適用しない限り、サブスクリプションのラインは単発購入になります。
</Warning>

交換はその場での編集ではなく、追加してから削除する処理なので、結果は**新しいライン**になります。新しい `key` が付与され、カートの末尾に配置されます。渡した key を再利用するのではなく、その後で `getCart()` を読み直してください。

***

<div id="refreshing">
  ## リフレッシュ
</div>

<div id="refresh">
  ### refresh()
</div>

Shopify からカートを再取得します。SDK の外部で何かがカートを変更し、ドロワーがそれに気付かなかった場合に使います。

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// After a raw Ajax API call of your own.
fetch('/cart/add.js', { method: 'POST', /* … */ })
  .then(() => window.aftersell.cart.actions.refresh())
  .then(() => { window.aftersell.cart.actions.open(); });
```

Aftersell はすでに Shopify の標準的なカートイベントをリッスンして自動で再取得するため、ほとんどの場合これは不要です。カスタム連携がそれらをバイパスする場合に使ってください。

<div id="visualrefresh">
  ### visualRefresh()
</div>

Shopify からカートを再取得せずに、レンダリング変換を再実行します。必要になることはまれです。[ライン変換](/ja/aftersell/cart/sdk-hooks#registerlinetransform)、[コンパレータ](/ja/aftersell/cart/sdk-hooks#registerlinecomparator)、[エンリッチャー](/ja/aftersell/cart/sdk-hooks#registercartenricher)、または[いずれかのサブスクリプションフック](/ja/aftersell/cart/sdk-hooks#registersubscriptionoptionstransform)を登録（または登録解除）すると、自動的に実行されます。画面上のものを何も変えない 2 つのカート追加フックだけは実行しません。

変換が*依存している*ものが変わったのに、カート自体は変わっていないときに使ってください:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// A currency switcher changed the format: repaint prices already on screen.
window.myTheme.onCurrencyChange((currency) => {
  window.aftersell.cart.configure({ money_format: FORMATS[currency] });
  window.aftersell.cart.actions.visualRefresh();
});
```

***

<div id="notes-and-edge-cases">
  ## 注意点とエッジケース
</div>

* **非同期アクションは変更が確定した時点で解決されます。** await すれば、カートが実際に更新された後に処理を続けられます。
* **`getCart()` はコピーを返します。** 書き換えても実際のカートには何も起こりません。
* **ディスカウントコード用のアクションはありません。** 適用されたコードはカート（`discountCodes`、`totalDiscount`）とラインごと（`discountAllocations`）に読み取れます。買い物客は [Discount code](/ja/aftersell/cart/discount-code-block) ブロックからコードを適用します。
* **カート属性やメモ用のアクションはありません。** 属性はカートオブジェクトから読み取れます。買い物客は [Notes](/ja/aftersell/cart/notes-block) ブロックからメモを書き込みます。
* **ラインを削除せずに非表示にするには**、[`registerLineTransform`](/ja/aftersell/cart/sdk-hooks#registerlinetransform) を使ってください。削除は買い物客の合計金額を変えますが、非表示は変えません。

<div id="where-to-go-next">
  ## 次のステップ
</div>

* **[カートオブジェクト](/ja/aftersell/cart/sdk-cart-object)**: `getCart()` が返すもの。
* **[イベント](/ja/aftersell/cart/sdk-events)**: これらのアクションを実行すべきタイミング。
* **[フック](/ja/aftersell/cart/sdk-hooks)**: カートを変更する代わりに、ラインのレンダリング方法を変更します。
* **[ユースケース](/ja/aftersell/cart/sdk-use-cases)**: よくある要望に対する完全なソリューション。
