Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

typescript - Angular2 cast a json result to an interface

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share

2.1m questions

2.1m answers

63 comments

56.6k users

...