Array Length Validator
Array Length Validator
Section titled “Array Length Validator”The arrayLength validator ensures that an array has a specific length within a defined range.
Syntax
Section titled “Syntax”validators.arrayLength(min: number, max?: number): StateValidatorParameters
Section titled “Parameters”- min- Minimum allowed array length (inclusive)
- max- Maximum allowed array length (inclusive, optional)
Basic Usage
Section titled “Basic Usage”import { withLocalState, validators } from 'phaser-hooks';
export class GameScene extends Phaser.Scene {  create() {    // Inventory must have between 1 and 20 items    const inventory = withLocalState(this, 'inventory', [], {      validator: validators.arrayLength(1, 20)    });
    // Player team must have exactly 4 members    const team = withLocalState(this, 'team', [], {      validator: validators.arrayLength(4, 4)    });
    // Quest log must have at least 1 quest    const quests = withLocalState(this, 'quests', [], {      validator: validators.arrayLength(1)    });  }}import { withLocalState, validators } from 'phaser-hooks';
export class GameScene extends Phaser.Scene {  create() {    // Inventory must have between 1 and 20 items    const inventory = withLocalState(this, 'inventory', [], {      validator: validators.arrayLength(1, 20)    });
    // Player team must have exactly 4 members    const team = withLocalState(this, 'team', [], {      validator: validators.arrayLength(4, 4)    });
    // Quest log must have at least 1 quest    const quests = withLocalState(this, 'quests', [], {      validator: validators.arrayLength(1)    });  }}Error Handling
Section titled “Error Handling”Always wrap state updates in try/catch blocks when using validators:
const inventory = withLocalState(this, 'inventory', [], {  validator: validators.arrayLength(1, 20)});
function addItem(item: any) {  try {    const currentItems = inventory.get();    const newItems = [...currentItems, item];    inventory.set(newItems);    console.log(`Added item. Inventory now has ${newItems.length} items`);  } catch (error) {    console.error('Invalid inventory size:', error.message);    // Handle the error - maybe remove oldest items    const currentItems = inventory.get();    if (currentItems.length >= 20) {      inventory.set(currentItems.slice(-19));    }  }}
function removeItem(index: number) {  try {    const currentItems = inventory.get();    const newItems = currentItems.filter((_, i) => i !== index);    inventory.set(newItems);  } catch (error) {    console.error('Invalid inventory size:', error.message);    // Handle the error - maybe add a default item    inventory.set([{ id: 'default', name: 'Default Item' }]);  }}const inventory = withLocalState(this, 'inventory', [], {  validator: validators.arrayLength(1, 20)});
function addItem(item) {  try {    const currentItems = inventory.get();    const newItems = [...currentItems, item];    inventory.set(newItems);    console.log(`Added item. Inventory now has ${newItems.length} items`);  } catch (error) {    console.error('Invalid inventory size:', error.message);    // Handle the error - maybe remove oldest items    const currentItems = inventory.get();    if (currentItems.length >= 20) {      inventory.set(currentItems.slice(-19));    }  }}
function removeItem(index) {  try {    const currentItems = inventory.get();    const newItems = currentItems.filter((_, i) => i !== index);    inventory.set(newItems);  } catch (error) {    console.error('Invalid inventory size:', error.message);    // Handle the error - maybe add a default item    inventory.set([{ id: 'default', name: 'Default Item' }]);  }}Common Use Cases
Section titled “Common Use Cases”Inventory Management
Section titled “Inventory Management”export class InventoryManager {  private items: HookState<any[]>;  private maxItems: number = 20;
  constructor(scene: Phaser.Scene) {    this.items = withLocalState(scene, 'inventory', [], {      validator: validators.arrayLength(1, this.maxItems)    });  }
  addItem(item: any) {    try {      const currentItems = this.items.get();      if (currentItems.length >= this.maxItems) {        throw new Error('Inventory is full');      }
      const newItems = [...currentItems, item];      this.items.set(newItems);      return true;    } catch (error) {      console.error('Failed to add item:', error.message);      return false;    }  }
  removeItem(itemId: string) {    try {      const currentItems = this.items.get();      const newItems = currentItems.filter(item => item.id !== itemId);      this.items.set(newItems);      return true;    } catch (error) {      console.error('Failed to remove item:', error.message);      // Ensure inventory has at least one item      this.items.set([{ id: 'default', name: 'Default Item' }]);      return false;    }  }}export class InventoryManager {  constructor(scene) {    this.maxItems = 20;    this.items = withLocalState(scene, 'inventory', [], {      validator: validators.arrayLength(1, this.maxItems)    });  }
  addItem(item) {    try {      const currentItems = this.items.get();      if (currentItems.length >= this.maxItems) {        throw new Error('Inventory is full');      }
      const newItems = [...currentItems, item];      this.items.set(newItems);      return true;    } catch (error) {      console.error('Failed to add item:', error.message);      return false;    }  }
  removeItem(itemId) {    try {      const currentItems = this.items.get();      const newItems = currentItems.filter(item => item.id !== itemId);      this.items.set(newItems);      return true;    } catch (error) {      console.error('Failed to remove item:', error.message);      // Ensure inventory has at least one item      this.items.set([{ id: 'default', name: 'Default Item' }]);      return false;    }  }}Team Management
Section titled “Team Management”export class TeamManager {  private team: HookState<any[]>;  private teamSize: number = 4;
  constructor(scene: Phaser.Scene) {    this.team = withLocalState(scene, 'team', [], {      validator: validators.arrayLength(this.teamSize, this.teamSize)    });  }
  addMember(member: any) {    try {      const currentTeam = this.team.get();      if (currentTeam.length >= this.teamSize) {        throw new Error('Team is full');      }
      const newTeam = [...currentTeam, member];      this.team.set(newTeam);      return true;    } catch (error) {      console.error('Failed to add team member:', error.message);      return false;    }  }
  removeMember(memberId: string) {    try {      const currentTeam = this.team.get();      const newTeam = currentTeam.filter(member => member.id !== memberId);      this.team.set(newTeam);      return true;    } catch (error) {      console.error('Failed to remove team member:', error.message);      // Team must have exactly 4 members, so we can't remove      return false;    }  }}export class TeamManager {  constructor(scene) {    this.teamSize = 4;    this.team = withLocalState(scene, 'team', [], {      validator: validators.arrayLength(this.teamSize, this.teamSize)    });  }
  addMember(member) {    try {      const currentTeam = this.team.get();      if (currentTeam.length >= this.teamSize) {        throw new Error('Team is full');      }
      const newTeam = [...currentTeam, member];      this.team.set(newTeam);      return true;    } catch (error) {      console.error('Failed to add team member:', error.message);      return false;    }  }
  removeMember(memberId) {    try {      const currentTeam = this.team.get();      const newTeam = currentTeam.filter(member => member.id !== memberId);      this.team.set(newTeam);      return true;    } catch (error) {      console.error('Failed to remove team member:', error.message);      // Team must have exactly 4 members, so we can't remove      return false;    }  }}Quest System
Section titled “Quest System”export class QuestManager {  private activeQuests: HookState<any[]>;  private maxQuests: number = 10;
  constructor(scene: Phaser.Scene) {    this.activeQuests = withLocalState(scene, 'activeQuests', [], {      validator: validators.arrayLength(1, this.maxQuests)    });  }
  addQuest(quest: any) {    try {      const currentQuests = this.activeQuests.get();      if (currentQuests.length >= this.maxQuests) {        throw new Error('Quest log is full');      }
      const newQuests = [...currentQuests, quest];      this.activeQuests.set(newQuests);      return true;    } catch (error) {      console.error('Failed to add quest:', error.message);      return false;    }  }
  completeQuest(questId: string) {    try {      const currentQuests = this.activeQuests.get();      const newQuests = currentQuests.filter(quest => quest.id !== questId);      this.activeQuests.set(newQuests);      return true;    } catch (error) {      console.error('Failed to complete quest:', error.message);      // Ensure at least one quest remains      this.activeQuests.set([{ id: 'default', name: 'Default Quest' }]);      return false;    }  }}export class QuestManager {  constructor(scene) {    this.maxQuests = 10;    this.activeQuests = withLocalState(scene, 'activeQuests', [], {      validator: validators.arrayLength(1, this.maxQuests)    });  }
  addQuest(quest) {    try {      const currentQuests = this.activeQuests.get();      if (currentQuests.length >= this.maxQuests) {        throw new Error('Quest log is full');      }
      const newQuests = [...currentQuests, quest];      this.activeQuests.set(newQuests);      return true;    } catch (error) {      console.error('Failed to add quest:', error.message);      return false;    }  }
  completeQuest(questId) {    try {      const currentQuests = this.activeQuests.get();      const newQuests = currentQuests.filter(quest => quest.id !== questId);      this.activeQuests.set(newQuests);      return true;    } catch (error) {      console.error('Failed to complete quest:', error.message);      // Ensure at least one quest remains      this.activeQuests.set([{ id: 'default', name: 'Default Quest' }]);      return false;    }  }}Error Messages
Section titled “Error Messages”The arrayLength validator returns specific error messages:
- "Value must be an array"- When the value is not an array
- "Array must have at least {min} items"- When the array is too short
- "Array must have at most {max} items"- When the array is too long
Important Notes
Section titled “Important Notes”- If maxis not provided, there’s no upper limit
- The validator only checks array length, not array content
- Empty arrays will fail if minis greater than 0
Next Steps
Section titled “Next Steps”- One Of Validator - Learn about enum validation
- Creating Custom Validators - Learn to create your own validators