6

I want to use [(ngModel)] for a nested object, but is giving me an error

Cannot read property 'mxn' of undefined

these are the data structure of my models:

company.model.ts

import Currency from './currency.model';

class Company {
_id: string;
name: string;
maxLimit: number;
source: [string];
deliveryMethod: [string];
currency: Currency;
date: Date;

constructor() {
    this.name = '';
    this.date = new Date();
    this.maxLimit = 0;
    this.source = [''];
    this.deliveryMethod = [''];
    this.currency.mxn = 0;
    this.currency.php = 0;
    }
}

export default Company;

currency.model.ts

class Currency {
mxn: number;
php: number;


constructor() {
    this.mxn = 0;
    this.php = 0;
}
}

export default Currency;

and this is part of company.ts

public newCompany: Company = new Company();
companiesList: Company[];
editcompanies: Company[] = [];

and HTML

in HTML page I'm able to show the mxn value by just using :

<tr class="companies" *ngFor="let company of companiesList">
{{company.currency.mxn}}

but when I want to use it with ngModel two-way binding for updating the value and sending it to the database it doesn't work.

[(ngModel)] = "newCompany.currency.mxn" it produces the mentioned error above. if I use [(ngModel)] = "newCompany.currency" it doesn't give me an error but the code it's useless since i can't assign any value to mxn.

I have to say that [(ngModel)] = "newCompany.name" it works fine with this and I can update the name.

the backend works fine as I tried it with Postman. the problem is angular side.

so the question is if my data structure is correct how can I use two-way binding for the nested object?

2
  • shouldn't you first instantiate the currency member in the company class constructor? Commented Dec 7, 2017 at 19:22
  • Thanks, you were all correct. it worked by just instantiating the currency. Commented Dec 7, 2017 at 20:38

3 Answers 3

3
currency: Currency;
...
constructor() {
  ...
  this.currency.mxn = 0;
  this.currency.php = 0;
}

mxn and php do not exist yet until you instantiate an instance of Currency. The instance currency is null. It doesn't contain any properties.

currency: Currency;
...
constructor() {
  ...
  this.currency = new Currency(); // invoke Currency constructor, create mxn and php with value 0, therefore you dont need this.currency.mxn = 0 and same to php
}
Sign up to request clarification or add additional context in comments.

Comments

2

A slight change in your Company model should be enough:

class Company {
  _id: string;
  name: string;
  maxLimit: number;
  source: [string];
  deliveryMethod: [string];
  currency: Currency = new Currency(); // provide an instance, otherwise this field will be undefined
  date: Date;

  constructor() {
      this.name = '';
      this.date = new Date();
      this.maxLimit = 0;
      this.source = [''];
      this.deliveryMethod = [''];
      this.currency.mxn = 0;
      this.currency.php = 0;
      }
  }

export default Company;

Comments

2

It looks like you're not instantiating the currency field in your constructor. Try by changing the

currency: Currency;

to

currency = new Currency();

It's probably working with your companiesList because probably (I'm guessing here) your backend instantiate them for you. And when you instantiate the newCompany which I assume you do by yourself it's not working cause of the missing new Currency()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.