Mongoose Schema - Declare multiple variables at once

I have a list of equipment slots for a RPG type character sheet. Each of the slots has a type like “head” or “body”, and each of them will have an object representing an item the character is wearing. Every piece of equipment will have the same variable types (as shown below) but I do not want to write each one separately because the list is very long. Is there a way to say “each of these types of equipment will have these variables”. Below is my attempt at it, but it doesn’t work (says “head is undefined”) or if I remove head (“body is undefined”) etc.

  equipment: {
    head,
    body,
    legs,
    feet,
    shoulders,
    arms,
    hands,
    back,
    ringLeft,
    ringRight,
    neck,
    rightHand,
    leftHand,
    ammunition: {
      default: {
        name: {
          type: String,
          default: "Empty"
        },
        Type: {
          type: String,
          default: ""
        },
        subType: {
          type: String,
          default: ""
        },
        handling: {
          type: String,
          default: ""
        },
        rarity: {
          type: String,
          default: ""
        },
        durability: {
          max: {
            type: Number,
            default: 0
          },
          current: {
            type: Number,
            default: 0
          }
        },
        damage: {
          min: {
            type: Number,
            default: 0
          },
          max: {
            type: Number,
            default: 0
          }
        },
        armorClass: {
          type: Number,
          default: 0
        },
        str: {
          type: Number,
          default: 0
        },
        dex: {
          type: Number,
          default: 0
        },
        int: {
          type: Number,
          default: 0
        },
        accuracy: {
          type: Number,
          default: 0
        },
        magicAccuracy: {
          type: Number,
          default: 0
        },
        magicDefense: {
          type: Number,
          default: 0
        },
        armorPiercing: {
          type: Number,
          default: 0
        },
        resistances: {
          fire: {
            type: Number,
            default: 0
          },
          ice: {
            type: Number,
            default: 0
          },
          lightning: {
            type: Number,
            default: 0
          },
          water: {
            type: Number,
            default: 0
          },
          earth: {
            type: Number,
            default: 0
          },
          wind: {
            type: Number,
            default: 0
          },
          light: {
            type: Number,
            default: 0
          },
          dark: {
            type: Number,
            default: 0
          }
        }
      }
    }
  }

How about creating a schema for nested set, say equipmentDetails, and then within your Equipment schema, you can set each property to point to that?

const EquipmentClassSchema= mongoose.Schema({
      default: {
        name: {
          type: String,
          default: "Empty"
        },
        Type: {
          type: String,
          default: ""
        },
        subType: {
          type: String,
          default: ""
        },
        handling: {
          type: String,
          default: ""
        },
        rarity: {
          type: String,
          default: ""
        },
        durability: {
          max: {
            type: Number,
            default: 0
          },
          current: {
            type: Number,
            default: 0
          }
        },
        damage: {
          min: {
            type: Number,
            default: 0
          },
          max: {
            type: Number,
            default: 0
          }
        },
        armorClass: {
          type: Number,
          default: 0
        },
        str: {
          type: Number,
          default: 0
        },
        dex: {
          type: Number,
          default: 0
        },
        int: {
          type: Number,
          default: 0
        },
        accuracy: {
          type: Number,
          default: 0
        },
        magicAccuracy: {
          type: Number,
          default: 0
        },
        magicDefense: {
          type: Number,
          default: 0
        },
        armorPiercing: {
          type: Number,
          default: 0
        },
        resistances: {
          fire: {
            type: Number,
            default: 0
          },
          ice: {
            type: Number,
            default: 0
          },
          lightning: {
            type: Number,
            default: 0
          },
          water: {
            type: Number,
            default: 0
          },
          earth: {
            type: Number,
            default: 0
          },
          wind: {
            type: Number,
            default: 0
          },
          light: {
            type: Number,
            default: 0
          },
          dark: {
            type: Number,
            default: 0
          }
        }
      }
    }
  }});

const EquipmentSchema = new mongoose.Schema({
    head: { 
        type: mongoose.Schema.Types.ObjectId, 
        ref: 'EquipmentClass'
    },
    body: { 
        type: mongoose.Schema.Types.ObjectId, 
        ref: 'EquipmentClass'
    },
    legs: { 
        type: mongoose.Schema.Types.ObjectId, 
        ref: 'EquipmentClass'
    },
    // ...
});

Great article on referencing one Schema from another (specifically, books and their authors). In your case, the equipment on a body part should be defined as a separate entity, so when it is removed or swapped with another, the attributes follow the equipment rather than the body part.

Thanks for the brain exercise!

1 Like

Hey, thank you. I think this is going to work.