0

I have created some functions on my objects, but these do not seem to register with angular/typescript... I think i know the reason why, but i dont know how to fix it, or maybe i am doing something wrong!

I have added an example here

This is a very simple example, but shows the problem i am having. If you open up the console, you will be able to see the exception i am talking about later.

So, in this example, i have 2 classes. MyParent and MyChild and they look like this

import { MyChild } from './MyChild'

export class MyParent {
  id: number;
  name: string;
  children: MyChild[] = [];
  addChild() {
    this.children.push(new MyChild());
  }

  constructor() {
    this.id = 1;
    this.name = 'parent object!';
  }
}

export class MyChild {
  id: number;
  name: string;

  constructor() {
    this.id = 0;
    this.name = 'new child';
    this.changeName = () => {
      this.name = new Date().toString();
    }
  }
}

Now all i want to do is be able to load this data from HTTP request, and call the method on MyParent object and method on MyChild object (example uses JSON.parse() as httpClientModule not available on webpackbin)

If you press the button "First parent Method", you will notice a child object is added to the first Parent object. Great! If you press the button "First child Method", the first child object in the collection has had its name changed! Great!

Now if you do the same for the second object, by pressing the buttons "Second parent method" and "Second child method" you get exceptions of

ERROR TypeError: item.addChild is not a function

AND

ERROR TypeError: item.changeName is not a function

Why? This object was created from text, so wonder if that has got something to do with it? But even if i change this line in the app.component.ts file i still get the same errors

this.second = JSON.parse(this.json);

to this

this.second = JSON.parse<MyParent>(this.json);

I can make the first parent function work if i change the code that loads the JSON data to use Object.assign, but this cannot be the fix, because although the parent method works, the child method does not!

this.second = Object.assign(new MyParent(), JSON.parse<MyParent>(this.json));

This example is just to show that the error happens. As i said, i want to use the HttpClientModule to load my data from an API, and even when i use the following code, it errors like above

this.httpClient.get<MyParent>('');

So i can only assume it is the same problem, and i am doing something wrong.

I can get round this problem on the parent object, is i used Object.assign

Help much appreciated.

Gillardo
  • 9,518
  • 18
  • 73
  • 141
  • `JSON.parse(this.json)` doesn't actually turn the JSON into a `MyParent` instance, *it just tells the compiler it already is one*. If you need an instance of the class, create one explicitly. – jonrsharpe Sep 15 '17 at 11:40
  • Possible duplicate of [How do I cast a JSON object to a typescript class](https://stackoverflow.com/questions/22875636/how-do-i-cast-a-json-object-to-a-typescript-class) – jonrsharpe Sep 15 '17 at 11:40
  • @jonrsharpe but i am loading my data from http API, I can call properties on the objects, so why not methods. – Gillardo Sep 15 '17 at 11:41
  • Why is that surprising? Just look at the JSON you're actually getting - it has the *properties*, but not the *methods*. You can't represent functions/methods in JSON. – jonrsharpe Sep 15 '17 at 11:42
  • I am sure it is working correctly, but when i pass in an object into my angular method of type MyParent, and it passes it in, why wouldnt i expect the properties and methods to be there... And i wrote the issur to help me figure out why it is so i can make it work the way i want it too – Gillardo Sep 15 '17 at 11:45
  • I don't really know how else to put it; you wouldn't expect it because that's not how TypeScript (or JSON or JS, for that matter) works. **The methods are not in the JSON**, as you can tell by looking at it; if you want an instance of the class with those methods you have to create it *from* the JSON representation. See also the proposed duplicate, https://stackoverflow.com/q/37310511/3001761 and numerous other related questions. – jonrsharpe Sep 15 '17 at 11:47

0 Answers0