everyAsync Method
The everyAsync()
method tests whether all elements in the collection satisfy the provided async testing function. Returns a Promise that resolves to a boolean value.
Basic Syntax
typescript
collect(items).everyAsync(callback: AsyncCallback<T, boolean>): Promise<boolean>
Examples
Basic Usage
typescript
import { collect } from 'ts-collect'
// Simple async validation
const numbers = collect([2, 4, 6, 8])
const allEven = await numbers.everyAsync(async (num) => {
await new Promise(resolve => setTimeout(resolve, 100))
return num % 2 === 0
})
console.log(allEven) // true
// External validation
const userIds = collect(['user1', 'user2', 'user3'])
const allActive = await userIds.everyAsync(async (userId) => {
const response = await fetch(`/api/users/${userId}/active`)
const { active } = await response.json()
return active
})
Working with Objects
typescript
interface Product {
id: string
sku: string
minStock: number
}
const products = collect<Product>([
{ id: '1', sku: 'WIDGET-1', minStock: 10 },
{ id: '2', sku: 'GADGET-1', minStock: 5 }
])
// Check if all products are in stock
const allInStock = await products.everyAsync(async (product) => {
const response = await fetch(`/api/inventory/${product.sku}/stock`)
const { quantity } = await response.json()
return quantity >= product.minStock
})
Real-world Examples
Order Validator
typescript
interface OrderItem {
productId: string
quantity: number
customizations: string[]
}
class OrderValidator {
constructor(private validationApi: string) {}
async validateOrder(items: Collection<OrderItem>): Promise<{
valid: boolean
reason?: string
}> {
try {
const allValid = await items.everyAsync(async (item) => {
const [stockValid, customizationsValid] = await Promise.all([
this.validateStock(item),
this.validateCustomizations(item)
])
return stockValid && customizationsValid
})
return {
valid: allValid,
reason: allValid ? undefined : 'One or more items failed validation'
}
} catch (error) {
return {
valid: false,
reason: error instanceof Error ? error.message : 'Unknown error'
}
}
}
private async validateStock(item: OrderItem): Promise<boolean> {
const response = await fetch(
`${this.validationApi}/stock/${item.productId}/${item.quantity}`
)
return response.json()
}
private async validateCustomizations(item: OrderItem): Promise<boolean> {
if (!item.customizations.length) return true
const results = await Promise.all(
item.customizations.map(async (customId) => {
const response = await fetch(
`${this.validationApi}/customization/${item.productId}/${customId}`
)
return response.json()
})
)
return results.every(result => result === true)
}
}
Shipping Validator
typescript
interface ShipmentItem {
orderId: string
destination: {
country: string
postal: string
}
weight: number
restrictions: string[]
}
class ShipmentValidator {
constructor(private shippingApi: string) {}
async canShipAll(shipments: Collection<ShipmentItem>): Promise<{
shippable: boolean
restrictions: string[]
}> {
const restrictions: string[] = []
const allShippable = await shipments.everyAsync(async (shipment) => {
const [
destinationValid,
weightValid,
restrictionsValid
] = await Promise.all([
this.validateDestination(shipment.destination),
this.validateWeight(shipment.weight),
this.validateRestrictions(shipment.restrictions)
])
if (!destinationValid) restrictions.push(`Invalid destination: ${shipment.orderId}`)
if (!weightValid) restrictions.push(`Invalid weight: ${shipment.orderId}`)
if (!restrictionsValid) restrictions.push(`Shipping restrictions: ${shipment.orderId}`)
return destinationValid && weightValid && restrictionsValid
})
return {
shippable: allShippable,
restrictions: allShippable ? [] : restrictions
}
}
private async validateDestination(destination: ShipmentItem['destination']): Promise<boolean> {
const response = await fetch(`${this.shippingApi}/validate-destination`, {
method: 'POST',
body: JSON.stringify(destination)
})
return response.json()
}
private async validateWeight(weight: number): Promise<boolean> {
const response = await fetch(`${this.shippingApi}/validate-weight/${weight}`)
return response.json()
}
private async validateRestrictions(restrictions: string[]): Promise<boolean> {
if (!restrictions.length) return true
const response = await fetch(`${this.shippingApi}/validate-restrictions`, {
method: 'POST',
body: JSON.stringify(restrictions)
})
return response.json()
}
}
Advanced Usage
Price Compliance Checker
typescript
interface PriceRule {
marketId: string
minPrice: number
maxPrice: number
currency: string
}
class PriceComplianceChecker {
constructor(
private exchangeRateApi: string,
private rules: PriceRule[]
) {}
async validatePriceCompliance(
products: Collection<{ sku: string; marketId: string; price: number }>
): Promise<{
compliant: boolean
violations: Array<{
sku: string
marketId: string
reason: string
}>
}> {
const violations: Array<{
sku: string
marketId: string
reason: string
}> = []
const allCompliant = await products.everyAsync(async (product) => {
const rule = this.rules.find(r => r.marketId === product.marketId)
if (!rule) {
violations.push({
sku: product.sku,
marketId: product.marketId,
reason: 'No price rules found for market'
})
return false
}
const convertedPrice = await this.convertPrice(
product.price,
rule.currency
)
const isCompliant = convertedPrice >= rule.minPrice &&
convertedPrice <= rule.maxPrice
if (!isCompliant) {
violations.push({
sku: product.sku,
marketId: product.marketId,
reason: `Price ${convertedPrice} outside allowed range ${rule.minPrice}-${rule.maxPrice}`
})
}
return isCompliant
})
return {
compliant: allCompliant,
violations
}
}
private async convertPrice(price: number, targetCurrency: string): Promise<number> {
const response = await fetch(
`${this.exchangeRateApi}/convert?price=${price}&to=${targetCurrency}`
)
const { convertedPrice } = await response.json()
return convertedPrice
}
}
Type Safety
typescript
interface ValidatableItem {
id: string
status: string
rules: string[]
}
const items = collect<ValidatableItem>([
{ id: '1', status: 'active', rules: ['A', 'B'] },
{ id: '2', status: 'active', rules: ['C'] }
])
// Type-safe async validation
const allValid = await items.everyAsync(async (item): Promise<boolean> => {
const response = await fetch(`/api/validate/${item.id}`)
return response.json()
})
// TypeScript enforces return type Promise<boolean>
const result: boolean = await allValid
Return Value
- Returns a Promise that resolves to a boolean
- Returns true if all items pass the test
- Returns false if any item fails
- Returns true for empty collections
- Executes tests in parallel
- Short-circuits on first false
Common Use Cases
1. Order Validation
- Stock availability
- Price validation
- Shipping rules
- Customer eligibility
- Payment verification
2. Inventory Checks
- Stock levels
- Availability
- Location validation
- Supplier checks
- Reorder points
3. Price Validation
- Market compliance
- Margin checks
- Discount rules
- Currency validation
- Price range checks
4. Shipping Validation
- Destination checks
- Weight limits
- Restrictions
- Service availability
- Cost validation
5. User Validation
- Permission checks
- Access rights
- Account status
- Usage limits
- Subscription status
6. Product Validation
- Availability
- Restrictions
- Category rules
- Feature availability
- Market compliance
7. Compliance Checks
- Legal requirements
- Policy compliance
- Regulatory checks
- Standard adherence
- Rule validation
8. Integration Validation
- API availability
- Service status
- Connection checks
- Resource access
- Response validation
9. Business Rules
- Policy enforcement
- Process validation
- Workflow rules
- Constraint checks
- Logic validation
10. Security Checks
- Access rights
- Token validation
- Rate limits
- Authentication
- Authorization