> ## 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.

# Actions

> Jede Aftersell Cart SDK-Action zum Lesen und Ändern des Warenkorbs: öffnen, schließen, hinzufügen, entfernen, Menge ändern, Variante tauschen, Zustand lesen und Geldbeträge formatieren.

Actions **lesen und ändern den Warenkorb**. Sie liegen unter `window.aftersell.cart.actions`.

<Note>
  Actions laufen, **nachdem der Warenkorb bereit ist** — innerhalb von `ready()` oder eines [Event](/de/aftersell/cart/sdk-events)-Handlers.
</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>
  **Bevor der Warenkorb lädt, sind Actions Stubs.** Jede protokolliert eine Konsolenwarnung mit dem Namen der Action, zum Beispiel `cart.actions.addItem() called before the cart loaded`, und tut nichts. Die asynchronen Actions lösen trotzdem ein Promise auf, sodass eine `.then()`-Kette normal läuft, statt zu werfen; `getCart()` gibt `null` zurück und `formatMoney()` einen leeren String.

  Nichts geht kaputt, wenn du eine zu früh aufrufst, aber es passiert auch nichts. Achte auf diese Warnung in der Konsole, wenn eine Action scheinbar nichts tut.
</Note>

<div id="every-action">
  ## Jede Action
</div>

| Action                                                   | Signatur                             | Rückgabe                | Was sie tut                          |
| -------------------------------------------------------- | ------------------------------------ | ----------------------- | ------------------------------------ |
| [`open`](#open-and-close)                                | `open()`                             | Keine                   | Öffnet den Drawer.                   |
| [`close`](#open-and-close)                               | `close()`                            | Keine                   | Schließt den Drawer.                 |
| [`getCart`](#getcart)                                    | `getCart()`                          | `AftersellCart \| null` | Liest den aktuellen Warenkorb.       |
| [`formatMoney`](#formatmoneycents)                       | `formatMoney(cents)`                 | `string`                | Formatiert einen Betrag zur Anzeige. |
| [`addItem`](#additemvariantid-quantity)                  | `addItem(variantId, quantity?)`      | `Promise`               | Fügt eine Variante hinzu.            |
| [`removeItem`](#removeitemkey)                           | `removeItem(key)`                    | `Promise`               | Entfernt eine Zeile.                 |
| [`updateItemQuantity`](#updateitemquantitykey-quantity)  | `updateItemQuantity(key, quantity)`  | `Promise`               | Setzt die Menge einer Zeile.         |
| [`replaceLineVariant`](#replacelinevariantkey-variantid) | `replaceLineVariant(key, variantId)` | `Promise`               | Tauscht die Variante einer Zeile.    |
| [`refresh`](#refresh)                                    | `refresh()`                          | `Promise`               | Lädt den Warenkorb neu von Shopify.  |
| [`visualRefresh`](#visualrefresh)                        | `visualRefresh()`                    | Keine                   | Rendert neu, ohne neu zu laden.      |

<Warning>
  Eine Action aus einem `cart_updated`-Handler aufzurufen kann eine Schleife erzeugen. Lies zuerst [die zwei Regeln](/de/aftersell/cart/sdk-events#the-two-rules).
</Warning>

***

<div id="drawer">
  ## Drawer
</div>

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

Öffnet oder schließt den Cart-Drawer. Beide sind synchron und nehmen keine Argumente.

```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">
  ## Lesen
</div>

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

Gibt das aktuelle [Cart-Objekt](/de/aftersell/cart/sdk-cart-object) zurück, oder `null`, bevor es geladen wurde. Das Ergebnis ist eine **Kopie**, das Mutieren ändert also nicht den echten Warenkorb.

```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));
});
```

Da es ein Snapshot ist, halte das Ergebnis nicht fest; lies es jedes Mal neu, wenn du aktuelle Daten brauchst. In einem Event-Handler hast du den frischen Warenkorb bereits als Payload, dort ist `getCart()` also redundant.

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

Formatiert einen Betrag in kleinster Einheit mit dem Geldformat deines Shops. Jeder Preis im SDK ist in Cents — so machst du daraus etwas Anzeigbares.

```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);
});
```

Überschreibe das Format mit [`configure({ money_format })`](/de/aftersell/cart/sdk-configure#money_format).

***

<div id="changing-the-cart">
  ## Den Warenkorb ändern
</div>

<Note>
  Die Item-Actions identifizieren eine Zeile über ihren Shopify-**`key`**, nicht über die Varianten-ID, weil ein Warenkorb dieselbe Variante in mehreren Zeilen mit unterschiedlichen Properties enthalten kann. Lies ihn aus `getCart().items[n].key`.
</Note>

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

Fügt dem Warenkorb eine Variante hinzu. `quantity` ist standardmäßig `1`. Wird aufgelöst, sobald sich der Warenkorb eingependelt hat.

```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);
```

Das Hinzufügen einer bereits im Warenkorb vorhandenen Variante erhöht die Menge dieser Zeile, statt eine zweite Zeile zu erstellen, solange die bestehende Zeile keine Line-Item-Properties hat. Eine Zeile mit Properties ist eine eigenständige Zeile, du bekommst also eine neue.

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

Entfernt eine Zeile vollständig.

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

Setzt die Menge einer Zeile. Die Übergabe von `0` entfernt die Zeile.

```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);
    }
  });
});
```

Das zweite Beispiel kann sicher aus `cart_updated` laufen, weil die `> 1`-Prüfung beim zweiten Durchlauf false ist. Siehe [die zwei Regeln](/de/aftersell/cart/sdk-events#the-two-rules).

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

Tauscht die Variante einer Zeile und behält dabei Menge und Properties. Nützlich für einen Größen- oder Geschmacks-Umschalter im Warenkorb.

```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>
  Der **Selling Plan der Zeile wird beim Tausch zurückgesetzt**. Eine Abo-Zeile wird zu einem Einmalkauf, es sei denn, du wendest einen Plan erneut an.
</Warning>

Der Tausch ist ein Hinzufügen gefolgt von einem Entfernen, keine Bearbeitung an Ort und Stelle — das Ergebnis ist also eine **neue Zeile**: Sie bekommt einen neuen `key` und landet am Ende des Warenkorbs. Lies `getCart()` danach neu, statt den übergebenen Key wiederzuverwenden.

***

<div id="refreshing">
  ## Aktualisieren
</div>

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

Lädt den Warenkorb neu von Shopify. Verwende es, nachdem etwas außerhalb des SDK den Warenkorb geändert hat und der Drawer es nicht bemerkt hat.

```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(); });
```

Meistens brauchst du das nicht, da Aftersell bereits auf Shopifys Standard-Warenkorb-Events lauscht und von selbst neu lädt. Greif dazu, wenn eine benutzerdefinierte Integration diese umgeht.

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

Führt die Render-Transformationen erneut aus, ohne den Warenkorb von Shopify neu zu laden. Du brauchst es selten: Das Registrieren (oder Deregistrieren) einer [Line-Transformation](/de/aftersell/cart/sdk-hooks#registerlinetransform), eines [Comparators](/de/aftersell/cart/sdk-hooks#registerlinecomparator), eines [Enrichers](/de/aftersell/cart/sdk-hooks#registercartenricher) oder eines der beiden [Subscription-Hooks](/de/aftersell/cart/sdk-hooks#registersubscriptionoptionstransform) löst eines für dich aus. Nur die zwei Add-to-cart-Hooks tun das nicht, da sie nichts ändern, was bereits auf dem Bildschirm ist.

Greif dazu, wenn sich etwas ändert, wovon eine Transformation *abhängt*, der Warenkorb selbst aber nicht:

```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">
  ## Hinweise und Randfälle
</div>

* **Asynchrone Actions werden aufgelöst, wenn die Änderung abgeschlossen ist.** Eine abzuwarten lässt dich Arbeit sequenzieren, nachdem der Warenkorb sich tatsächlich aktualisiert hat.
* **`getCart()` gibt eine Kopie zurück.** Sie zu mutieren tut dem echten Warenkorb nichts.
* **Es gibt keine Action für Rabattcodes.** Angewendete Codes sind auf dem Warenkorb (`discountCodes`, `totalDiscount`) und pro Zeile (`discountAllocations`) lesbar; Käufer wenden sie über den [Discount code](/de/aftersell/cart/discount-code-block)-Block an.
* **Es gibt keine Action für Warenkorb-Attribute oder Notizen.** Attribute sind auf dem Cart-Objekt lesbar; Käufer schreiben Notizen über den [Notes](/de/aftersell/cart/notes-block)-Block.
* **Um eine Zeile auszublenden statt zu entfernen,** verwende [`registerLineTransform`](/de/aftersell/cart/sdk-hooks#registerlinetransform). Entfernen ändert die Gesamtsumme des Käufers; Ausblenden nicht.

<div id="where-to-go-next">
  ## Nächste Schritte
</div>

* **[Cart-Objekt](/de/aftersell/cart/sdk-cart-object)**: was `getCart()` zurückgibt.
* **[Events](/de/aftersell/cart/sdk-events)**: wann du diese Actions ausführen solltest.
* **[Hooks](/de/aftersell/cart/sdk-hooks)**: ändere, wie eine Zeile gerendert wird, statt den Warenkorb zu ändern.
* **[Use Cases](/de/aftersell/cart/sdk-use-cases)**: vollständige Lösungen für häufige Anforderungen.
