# Address Actions API

Address actions allow you to programmatically manage the delivery location.

## actions.address.setAddressByPlacesId()

Set address using a Google Places ID.

### Signature

```typescript
setAddressByPlacesId(placesId: string): Promise<void>
```

### Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `placesId` | string | Yes | Google Places ID |

### Example

```javascript
await window.LiquidCommerce.elements.actions.address.setAddressByPlacesId(
  'ChIJOwg_06VPwokRYv534QaPC8g'
);
```

### How to Get Places ID

Visit [Google Place IDs](https://developers.google.com/maps/documentation/places/web-service/place-id#find-id) for details on obtaining a Places ID.

---

## actions.address.setAddressManually()

Set address manually without Google Places.

### Signature

```typescript
setAddressManually(
  address: IAddressAddress,
  coordinates: IAddressCoordinates
): Promise<void>
```

### Parameters

```typescript
interface IAddressAddress {
  one: string;    // Street address
  two?: string;   // Apt, suite, etc. (optional)
  city: string;   // City name
  state: string;  // Two-letter state code
  zip: string;    // ZIP/postal code
}

interface IAddressCoordinates {
  latitude: number;   // -90 to 90
  longitude: number;  // -180 to 180
}
```

### Example

```javascript
await window.LiquidCommerce.elements.actions.address.setAddressManually(
  {
    one: '123 Main Street',
    two: 'Apt 4',
    city: 'New York',
    state: 'NY',
    zip: '10001'
  },
  {
    latitude: 40.7128,
    longitude: -74.0060
  }
);
```

### Validation

The SDK validates:
- All required fields are present
- State is 2-letter code
- Latitude is between -90 and 90
- Longitude is between -180 and 180

### Errors

**Throws `SDKError` if:**
- Required fields are missing
- Coordinates are out of range
- Address format is invalid

---

## actions.address.clear()

Remove the current address.

### Signature

```typescript
clear(): Promise<void>
```

### Example

```javascript
await window.LiquidCommerce.elements.actions.address.clear();
```

### Effects

- Clears stored address
- Products will prompt for address on next add-to-cart
- Cart/checkout require re-entering address

---

## actions.address.getDetails()

Retrieve the current address.

### Signature

```typescript
getDetails(): IAddressData | null
```

### Returns

```typescript
interface IAddressData {
  id: string;  // Google Places ID or generated ID
  address: {
    one: string;
    two?: string;
    city: string;
    state: string;
    zip: string;
  };
  coordinates: {
    latitude: number;
    longitude: number;
  };
  formattedAddress: string;
}
```

Returns `null` if no address is set.

### Example

```javascript
const address = window.LiquidCommerce.elements.actions.address.getDetails();

if (address) {
  console.log('Current address:', address.formattedAddress);
  console.log('Coordinates:', address.coordinates);
} else {
  console.log('No address set');
}
```

### Use Cases

#### Check if Address is Set

```javascript
if (!window.LiquidCommerce.elements.actions.address.getDetails()) {
  // Prompt user to set address
  showAddressPrompt();
}
```

#### Display Current Address

```javascript
const address = window.LiquidCommerce.elements.actions.address.getDetails();

if (address) {
  document.getElementById('current-address').textContent = 
    address.formattedAddress;
}
```
## Events

Address actions trigger events:

```javascript
// Address updated
window.addEventListener('lce:actions.address_updated', (event) => {
  const { address, coordinates, formattedAddress } = event.detail.data;
  console.log('Address set:', formattedAddress);
});

// Address cleared
window.addEventListener('lce:actions.address_cleared', () => {
  console.log('Address cleared');
});

// Address failed
window.addEventListener('lce:actions.address_failed', (event) => {
  console.error('Address error:', event.detail.data.error);
});
```

## Best Practices

### Use Places ID When Available

Google Places provides accurate geocoding:

```javascript
// Good - accurate and validated
await window.LiquidCommerce.elements.actions.address.setAddressByPlacesId(placesId);

// Less ideal - requires manual geocoding
await window.LiquidCommerce.elements.actions.address.setAddressManually(address, coords);
```

### Validate Manual Addresses

When using manual address entry:

```javascript
async function setManualAddress(address, coords) {
  // Validate format
  if (!address.one || !address.city || !address.state || !address.zip) {
    throw new Error('Missing required fields');
  }
  
  // Validate state
  if (!/^[A-Z]{2}$/.test(address.state)) {
    throw new Error('State must be 2-letter code');
  }
  
  // Validate ZIP
  if (!/^\d{5}(-\d{4})?$/.test(address.zip)) {
    throw new Error('Invalid ZIP code');
  }
  
  await window.LiquidCommerce.elements.actions.address.setAddressManually(address, coords);
}
```

### Handle Errors

```javascript
try {
  await window.LiquidCommerce.elements.actions.address.setAddressByPlacesId(placesId);
  showSuccess('Address saved!');
} catch (error) {
  console.error('Failed to set address:', error);
  showError('Unable to set that address. Please try again.');
}
```

### Set Address Early

Set address as soon as possible in user flow:

```javascript
window.addEventListener('lce:actions.client_ready', () => {
  if (!window.LiquidCommerce.elements.actions.address.getDetails()) {
    // Prompt for address on first visit
    showAddressModal();
  }
});
```

## See Also

- [Address Component Guide](../../guides/address-component.md)
- [Address Events](../../guides/events.md#address-events)
- [Product Component](../../guides/product-component.md#address-requirement)
- [Cart Component](../../guides/cart-component.md#address-requirement)
