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

> Alle Aftersell Cart SDK-actions til at læse og ændre kurven: åbn, luk, tilføj, fjern, opdater antal, skift variant, læs tilstand og formatér beløb.

Actions **læser og ændrer kurven**. De ligger under `window.aftersell.cart.actions`.

<Note>
  Actions kører, **efter kurven er klar**, inde i `ready()` eller en [event](/da/aftersell/cart/sdk-events)-handler.
</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>
  **Før kurven indlæses, er actions stubbe.** Hver enkelt logger en konsoladvarsel, der nævner actionen, for eksempel `cart.actions.addItem() called before the cart loaded`, og gør ingenting. De asynkrone actions resolver stadig et Promise, så en `.then()`-kæde kører normalt i stedet for at kaste en fejl; `getCart()` returnerer `null`, og `formatMoney()` returnerer en tom streng.

  Intet går i stykker, hvis du kalder en for tidligt, men der sker heller ikke noget. Hold øje med konsollen for den advarsel, når en action ser ud til ikke at gøre noget.
</Note>

<div id="every-action">
  ## Alle actions
</div>

| Action                                                   | Signatur                             | Returnerer              | Hvad den gør                     |
| -------------------------------------------------------- | ------------------------------------ | ----------------------- | -------------------------------- |
| [`open`](#open-and-close)                                | `open()`                             | Ingen                   | Åbner draweren.                  |
| [`close`](#open-and-close)                               | `close()`                            | Ingen                   | Lukker draweren.                 |
| [`getCart`](#getcart)                                    | `getCart()`                          | `AftersellCart \| null` | Læser den aktuelle kurv.         |
| [`formatMoney`](#formatmoneycents)                       | `formatMoney(cents)`                 | `string`                | Formaterer et beløb til visning. |
| [`addItem`](#additemvariantid-quantity)                  | `addItem(variantId, quantity?)`      | `Promise`               | Tilføjer en variant.             |
| [`removeItem`](#removeitemkey)                           | `removeItem(key)`                    | `Promise`               | Fjerner en linje.                |
| [`updateItemQuantity`](#updateitemquantitykey-quantity)  | `updateItemQuantity(key, quantity)`  | `Promise`               | Sætter en linjes antal.          |
| [`replaceLineVariant`](#replacelinevariantkey-variantid) | `replaceLineVariant(key, variantId)` | `Promise`               | Skifter en linjes variant.       |
| [`refresh`](#refresh)                                    | `refresh()`                          | `Promise`               | Genhenter kurven fra Shopify.    |
| [`visualRefresh`](#visualrefresh)                        | `visualRefresh()`                    | Ingen                   | Gentegner uden at genhente.      |

<Warning>
  At kalde en action fra en `cart_updated`-handler kan skabe en løkke. Læs [de to regler](/da/aftersell/cart/sdk-events#the-two-rules) først.
</Warning>

***

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

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

Åbn eller luk cart draweren. Begge er synkrone og tager ingen argumenter.

```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">
  ## Læsning
</div>

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

Returnerer det aktuelle [cart-objekt](/da/aftersell/cart/sdk-cart-object), eller `null` før det er indlæst. Resultatet er en **kopi**, så at mutere det ændrer ikke den rigtige kurv.

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

Fordi det er et øjebliksbillede, skal du ikke holde fast i resultatet; læs det igen, hver gang du har brug for aktuelle data. I en event handler har du allerede den friske kurv som payload, så `getCart()` er overflødig der.

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

Formaterer et beløb i mindste enhed ved hjælp af din butiks pengeformat. Alle priser i SDK'et er i cents, så det er sådan, du gør en af dem til noget, du kan vise.

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

Tilsidesæt formatet med [`configure({ money_format })`](/da/aftersell/cart/sdk-configure#money_format).

***

<div id="changing-the-cart">
  ## Ændring af kurven
</div>

<Note>
  Vare-actions identificerer en linje via dens Shopify-**`key`**, ikke via variant-ID, fordi en kurv kan indeholde den samme variant på flere linjer med forskellige properties. Læs den fra `getCart().items[n].key`.
</Note>

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

Tilføjer en variant til kurven. `quantity` er som standard `1`. Resolver, når kurven har stabiliseret sig.

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

Tilføjelse af en variant, der allerede er i kurven, øger den linjes antal frem for at oprette en anden linje, så længe den eksisterende linje ikke har varelinje-properties. En linje med properties er en særskilt linje, så du får en ny.

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

Fjerner en linje helt.

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

Sætter en linjes antal. Sendes `0`, fjernes linjen.

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

Det andet eksempel er sikkert at køre fra `cart_updated`, fordi `> 1`-tjekket er falsk ved anden gennemkørsel. Se [de to regler](/da/aftersell/cart/sdk-events#the-two-rules).

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

Skifter en linjes variant, mens dens antal og properties bevares. Nyttig til en størrelses- eller smagsskifter inde i kurven.

```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>
  Linjens **selling plan nulstilles** ved et skift. En abonnementslinje bliver et engangskøb, medmindre du genanvender en plan.
</Warning>

Skiftet er en tilføjelse efterfulgt af en fjernelse, ikke en redigering på stedet, så resultatet er en **ny linje**: den får en ny `key` og lander i slutningen af kurven. Genlæs `getCart()` bagefter i stedet for at genbruge den key, du sendte ind.

***

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

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

Genhenter kurven fra Shopify. Brug den, efter at noget uden for SDK'et har ændret kurven, og draweren ikke opdagede det.

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

Det meste af tiden har du ikke brug for denne, da Aftersell allerede lytter efter Shopifys standard-kurvevents og selv genhenter. Ræk ud efter den, når en brugerdefineret integration omgår dem.

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

Kører render-transformationerne igen uden at genhente kurven fra Shopify. Du har sjældent brug for den: registrering (eller afregistrering) af en [line transform](/da/aftersell/cart/sdk-hooks#registerlinetransform), [comparator](/da/aftersell/cart/sdk-hooks#registerlinecomparator), [enricher](/da/aftersell/cart/sdk-hooks#registercartenricher) eller et af de to [abonnements-hooks](/da/aftersell/cart/sdk-hooks#registersubscriptionoptionstransform) udløser én for dig. Kun de to add to cart-hooks gør det ikke, da de ikke ændrer noget, der allerede er på skærmen.

Ræk ud efter den, når noget, en transformation *afhænger af*, ændres, men kurven selv ikke har:

```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">
  ## Noter og kanttilfælde
</div>

* **Asynkrone actions resolver, når ændringen har stabiliseret sig.** At awaite en lader dig sekvensere arbejde, efter kurven faktisk er opdateret.
* **`getCart()` returnerer en kopi.** At mutere den gør intet ved den rigtige kurv.
* **Der er ingen action til rabatkoder.** Anvendte koder kan læses på kurven (`discountCodes`, `totalDiscount`) og pr. linje (`discountAllocations`); kunder anvender dem via [Discount code](/da/aftersell/cart/discount-code-block)-blokken.
* **Der er ingen action til kurvattributter eller noter.** Attributter kan læses på cart-objektet; kunder skriver noter via [Notes](/da/aftersell/cart/notes-block)-blokken.
* **For at skjule en linje i stedet for at fjerne den** skal du bruge [`registerLineTransform`](/da/aftersell/cart/sdk-hooks#registerlinetransform). Fjernelse ændrer kundens total; skjulning gør ikke.

<div id="where-to-go-next">
  ## Hvor skal du hen nu
</div>

* **[Cart-objekt](/da/aftersell/cart/sdk-cart-object)**: hvad `getCart()` giver tilbage.
* **[Events](/da/aftersell/cart/sdk-events)**: hvornår du skal køre disse actions.
* **[Hooks](/da/aftersell/cart/sdk-hooks)**: ændr, hvordan en linje renderes, i stedet for at ændre kurven.
* **[Use cases](/da/aftersell/cart/sdk-use-cases)**: komplette løsninger på almindelige ønsker.
