Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 cast a json result to an interface

Tags:

Using Angular2 and typescript, I have JSON returned from a webApi and I need to get it into an array of a certain type. I can't figure out how to cast the json to the interface I need.

My type is this interface:

export interface Country {     Id: number;     Name: string; } 

My mock returns this array:

export var COUNTRIES: Country[] = [     { "Id": 11, "Name": "US" },     { "Id": 12, "Name": "England" },     { "Id": 13, "Name": "Japan" } ]; 

Here is my code: country.service.ts

@Injectable() export class CountryService {     private _http = null;      constructor(http: Http) {         this._http = http;     }      getCountries() {         return Promise.resolve(COUNTRIES);     } } 

Then I call it with this:

export class CountryPickerComponent {     public countries: Country[];      constructor(private _countryService: CountryService) { }       getCountries() {         this._countryService.getCountries().then(data => this.setData(data));     }      setData(data) {         //this.countries = data;         this.countries = JSON.parse(data);         var q = 1;     }      ngOnInit() {         this.getCountries();     } }   

As you can see, I have a class variable called countries that is an array of the Country interface. This works as expected. (I know I don't need that setData method - it's for debugging)

Next, I changed the service to a wepApi call which returns this json.

"[{"name":"England","id":1},{"name":"France","id":2}]" 

I changed the getCountries method in the service to:

getCountries() {     return new Promise(resolve=>         this._http.get('http://localhost:63651/Api/membercountry')             .subscribe(data => resolve(data.json()))     ); } 

Using JSON.parse, I convert this to an array which I can then use in angular2. It works. It creates the array with the data. But it's not an array implementing the Country interface.

Notice that the field names from the JSON are all lower case, but the interface properties starts with an uppercase and I coded to the interface. As a result, when I got the real json it does not work. Is there a way to 'cast' this to the interface, which should throw an error and let me know something is wrong?

Many examples use map in the get as shown below:

  getCountries() {         var retVal;          return new Promise(resolve=>             this._http.get('http://localhost:63651/Api/membercountry')                 .map(ref => ref.json())                 .subscribe(data => resolve(data.json()))         );     } 

I can't find documentation on this. When I try it I never get data but there is no error. No compile error and no runtime error.

like image 906
Don Chambers Avatar asked Dec 29 '15 17:12

Don Chambers


People also ask

How do I cast a JSON object to a TypeScript interface?

1) Add a constructor in your Typescript class that takes the json data as parameter. In that constructor you extend your json object with jQuery, like this: $. extend( this, jsonData) .

How do you get a specific value from a JSON object in TypeScript?

To parse a JSON string in TypeScript, you can use JSON. parse().

How do I Stringify a JSON object in TypeScript?

Stringify a JavaScript ObjectUse the JavaScript function JSON.stringify() to convert it into a string. const myJSON = JSON.stringify(obj); The result will be a string following the JSON notation.

What is JSON Stringify?

The JSON.stringify() method converts a JavaScript value to a JSON string, optionally replacing values if a replacer function is specified or optionally including only the specified properties if a replacer array is specified.


1 Answers

You can do a type assertion to the interface you are expecting on the object created by JSON.parse.

 this.http.get('http://localhost:4200/').subscribe((value: Response) => {     let hero = <ServerInfo>value.json();   }); 

However this will not result in any errors if the server sends you bad objects because of 2 reasons.

At compile time the transpiler does not know what the server will send.

At runtime all type information is erased since everything gets compiled to javascript.

like image 64
toskv Avatar answered Nov 06 '22 19:11

toskv