-1

t.budget.budgetGroup.name here it has above error. I cannot recreate this error. But Sentry shows it as a runtime exception. Is this possible? Since I have initialized the new Budget() and new BudgetGroup(). So how can I fix this?

  data: DtoBudgetGroup;

  constructor(){}

  init() {
    this.data = this.navParams.get('data');
  }

let filteredTransactions: Transaction[] = filter(this.data.transactions, (t: 
Transaction) => { return t.budget.budgetGroup.name == this.data.budget.budgetGroup.name; });

export class Transaction {
    id: string;
    budget: Budget = new Budget();
  }

export class Budget {
    id: string;
    budgetGroup: BudgetGroup = new BudgetGroup();    
}

export class BudgetGroup {
    id: string;
    name: string;

}

export class DtoBudgetGroup {
    budget: Budget;
    budgetGroup: BudgetGroup;
    budgetTotal: number;
    transactionTotal: number;
    transactions: Transaction[];
    isTransactionOver: boolean = false;
}

this.data = this.navParams.get('data');

enter image description here

Sampath
  • 63,341
  • 64
  • 307
  • 441
  • It depends on how this.data.transactions is initialized. If it is the response of a web API then your classes will not be instantiated by itself. You need to instantiate once you get JSON data by mapping that JSON data to your desired class collection. – user2216584 Jun 10 '19 at 16:56
  • @user2216584 I have added more data. Please see it. No API. This is `Firestore` data. – Sampath Jun 10 '19 at 17:00
  • Yep you called it @user2216584 - an async problem - not a typescript problem. – Randy Casburn Jun 10 '19 at 17:02
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Randy Casburn Jun 10 '19 at 17:02
  • 1
    @RandyCasburn You're WRONG. Here data is on upfront. No async issue here. Please read the question clearly. `this.data = this.navParams.get('data')` – Sampath Jun 10 '19 at 17:03
  • 1
    @Sampath Can you please share the output of console.log(this.data) after line this.data = this.navParams.get('data'); – user2216584 Jun 10 '19 at 17:04
  • @user2216584 Done that. – Sampath Jun 10 '19 at 17:11
  • @Sampath - can you please complete your code so we can see the rest of that initial class? – Randy Casburn Jun 10 '19 at 17:12
  • Can you remove your dup and see the new update? @RandyCasburn – Sampath Jun 10 '19 at 17:12
  • I'm not convinced it not a dup yet. But I will when I'm convinced. – Randy Casburn Jun 10 '19 at 17:13
  • The code you've posted makes no sense: 1) create `data` typed as `DtoBudgetGroup`, 2) an empty `constructor`, which will throw at runtime as written, 3) an `init()` function that never get's called 4) `filteredTransactions` assignment that runs `filter()` - this is the first line of code executed and will produce the error for certain as `data` is empty at that point. Please put the rest of that top class together and let us see the `navParams.get` method. – Randy Casburn Jun 10 '19 at 17:26
  • `console.log(t)` and you will see for sure an empty object – Sergey Jun 10 '19 at 17:26

1 Answers1

-2

The problem in your code is that when you type

class MyClass {

prop: stirng;

}

You are only declaring a set of properties and their type.

However, you don't initialise them. To initialise you need a constructor.

You have two ways of declaring class' props

export class BudgetGroup {
  constructor(
      public id?: string,
      public name?: string
    ) {
    }
}

and

export class BudgetGroup {
    id: string;
    name: string;

     constructor(
      id: string,
      name: string
    ) {
      this.id = id;
      this.name = name;
    }
}

The example you can see here


There is no prop initialisation therefore calling new BudgetGroup results in empty object. To initialise them you should use either constructor where you pass props or declare these props values right in class.

Update. Specially for Randy Casburn

enter image description here

Sergey
  • 7,184
  • 13
  • 42
  • 85
  • Even if this answer were NOT completely incorrect, it does not answer the OP's question about `BudgetGroup` properties - which has been initialized. – Randy Casburn Jun 10 '19 at 17:00
  • @RandyCasburn It does answer the question. 2) The props were not initialised and this can be seen on my link `const a`. – Sergey Jun 10 '19 at 17:04
  • This: **_To initialise you need a constructor._** - is just wrong. And your link points that out too. – Randy Casburn Jun 10 '19 at 17:10
  • The initialization for this `name` property is supposed to occur in the `filter()` call, where an assignment statement is being made to `t.budget.budgetGroup.name` from the data retrieved from the `init()` method. The OP is initializing the properties. Just _not_ at construction time. This is a post object creation assignment. And thanks for the call out !! – Randy Casburn Jun 10 '19 at 17:21
  • @RandyCasburn Have you tried to create an object that OP has build with only interface providing? TypeScript works that way. You either initialise values in constructor or right at declaration but it requires values to be. Even `null` will work for that. In this case the Interface is being created without props. – Sergey Jun 10 '19 at 17:25
  • Let me try this then. here is the error as the OP posted it: _Cannot set property "name" of undefined_ - it isn't `name` that is undefined. it is one of the two other objects that have a `name` property. We don't know which one it is. You can see in your own blitz that both objects are certainly there. – Randy Casburn Jun 10 '19 at 17:34
  • @RandyCasburn He's trying to make a `DtoBudgetGroup` instance which has `budget` prop with prop `name` in it. So the route is `dto->budget->name`. Since props weren't initialised the actual prop route looks like this `dto->undefined->'name'`. Therefore, the error is `name of undefined` – Sergey Jun 10 '19 at 18:54