Skip to main content
The order service exposes past and pending orders for the current customer. Reads are on-demand — there’s no reactive list signal, so blocks fetch when they need data.

Setup

import {
  provideContext,
  createOrderService,
  createApiOrderAdapter,
  OrderServiceContext,
} from "@juo/blocks";

provideContext(
  root,
  OrderServiceContext,
  createOrderService(createApiOrderAdapter({ baseUrl: "/api/v1" })),
);

Shape

type Order = {
  id: string;
  customerId: string;
  items: OrderItem[];
  deliveryDate: string | null;
  status: "pending" | "confirmed" | "delivered" | "skipped";
  metadata?: Record<string, unknown>;
};

type OrderItem = {
  id: string;
  productId: string;
  variantId: string;
  quantity: number;
  metadata?: Record<string, unknown>;
};

type OrderService = {
  getHistory(): Promise<Result<Order[]>>;
  getById(id: string): Promise<Result<Order | null>>;
};

Example: order history list

import { defineBlock, injectContext, OrderServiceContext } from "@juo/blocks";

defineBlock("OrderHistory", {
  group: "theme",
  schema: { /* ... */ } as const,
  initialValue: () => ({ props: {} }),
  renderer(block) {
    const el = document.createElement("ul");
    const orderService = injectContext(el, OrderServiceContext);

    orderService.getHistory().then((result) => {
      if (result._tag !== "Success") return;
      el.replaceChildren(
        ...result.data.map((order) => {
          const li = document.createElement("li");
          li.textContent = `${order.status}${order.deliveryDate ?? "no date"}`;
          return li;
        }),
      );
    });

    return el;
  },
});