Nozbe / WatermelonDB

🍉 Reactive & asynchronous database for powerful React and React Native apps ⚡️
https://watermelondb.dev
MIT License
10.62k stars 600 forks source link

TypeError: Cannot read property 'type' of undefined #1795

Closed RattyJhay closed 6 months ago

RattyJhay commented 6 months ago

I get this error when I try to create a transaction in the db. These are the schemas:

 tableSchema({
      name: "accounts",
      columns: [
        { name: "name", type: "string", isIndexed: true },
        { name: "balance", type: "number" },
        { name: "icon", type: "string" },
        { name: "color", type: "string" },
        { name: "available_balance", type: "number" },
        { name: "created_at", type: "number" },
        { name: "updated_at", type: "number" },
      ],
    }),
    tableSchema({
      name: "categories",
      columns: [
        { name: "name", type: "string", isIndexed: true },
        { name: "color", type: "string" },
        { name: "icon", type: "string" },
        { name: "created_at", type: "number" },
        { name: "updated_at", type: "number" },
      ],
    }),
    tableSchema({
      name: "transactions",
      columns: [
        { name: "title", type: "string" },
        { name: "amount", type: "number" },
        { name: "date", type: "string", isIndexed: true },
        { name: "description", type: "string" },
        { name: "type", type: "string" },
        { name: "category_id", type: "string", isIndexed: true },
        { name: "account_id", type: "string", isIndexed: true },
        { name: "time", type: "string" },
        { name: "created_at", type: "number" },
        { name: "updated_at", type: "number" },
      ],
    }),

And these are the models. I'm using // @ts-ignore because i get this error when i don't Property 'accountName' has no initializer and is not definitely assigned in the constructor. the only way to fix it to add an undefined type to it

export default class Accounts extends Model {
  static table = "accounts";
  static associations: Associations = {
    transactions: { type: "has_many", foreignKey: "accounts_id" },
    budgets: { type: "has_many", foreignKey: "accounts_id" },
    planned_payments: { type: "has_many", foreignKey: "accounts_id" },
    account_transfers: { type: "has_many", foreignKey: "accounts_id" },
  };

  // @ts-ignore
  @text("name") accountName: string;
  // @ts-ignore
  @text("icon") icon: string;
  // @ts-ignore
  @text("color") color: string;
  // @ts-ignore
  @field("balance") accountBalance: number;
  // @ts-ignore
  @field("available_balance") availableBalance: number;
  // @ts-ignore
  @readonly @date("created_at") createdAt: number;
  // @ts-ignore
  @readonly @date("updated_at") updatedAt: number;

  // @ts-ignore
  @children("transactions") transactions;
  // @ts-ignore
  @children("budgets") budgets;
  // @ts-ignore
  @children("planned_payments") planned_payments;
  // @ts-ignore
  @children("account_transfers") account_transfers;
}

export default class Transactions extends Model {
  static table = "transactions";

  static associations: Associations = {
    accounts: { type: "belongs_to", key: "accounts_id" },
    categories: { type: "belongs_to", key: "categories_id" },
  };

  // @ts-ignore
  @text("title") title: string;

  // @ts-ignore
  @field("amount") amount: number;

  // @ts-ignore
  @date("date") date: string;

  // @ts-ignore
  @date("time") time: string;

  // @ts-ignore
  @text("description") description: string;

  // @ts-ignore
  @text("type") type: string;

  // @ts-ignore
  @relation("category_id", "categories_id") categoryId;

  // @ts-ignore
  @relation("accounts_id", "accounts_id") accountId;

  // @ts-ignore
  @readonly @date("created_at") createdAt: Date;

  // @ts-ignore
  @readonly @date("updated_at") updatedAt: Date;
}

export default class Categories extends Model {
  static table = "categories";

  static associations: Associations = {
    transactions: { type: "has_many", foreignKey: "categories_id" },
    budget_categories: { type: "has_many", foreignKey: "categories_id" },
  };

  // @ts-ignore
  @text("name") name: string;

  // @ts-ignore
  @field("color") color: string;

  // @ts-ignore
  @field("icon") icon: string;

  // @ts-ignore
  @readonly @date("created_at") createdAt: number;

 // @ts-ignore
  @readonly @date("updated_at") updatedAt: number;
}

and this is the code for creating a transaction.

 const trns = await database.write(async () => {
      const acc = await AccountsCollections.find(accountId);
      const cat = await CategoriesCollections.find(categoryId);

      await TransactionsCollections.create((trns) => {
        (trns.title = transactionData.title),
          (trns.amount = transactionData.amount),
          trns.accountId.set(acc.id),
          trns.categoryId.set(cat.id),
          (trns.date = date),
          (trns.time = time),
          (trns.type = transactionData.type),
          (trns.description = description);
      });
    });

this is a representation of what the data should look like:

{
  accountId: "uskVGi05ZruxBbJM",
  amount: 1000,
  categoryId: "bx7EWPhoHabh2nOe",
  date: "2024-05-01 00:49:00",
  description: "",
  time: "2024-05-01 00:49:00",
  title: "Phone",
  type: "Expense",
}