I'm new to Angular and am struggling to build my first app. I have a web service which returns some json in this format:
<PolicyHolderClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<Title>Mr</Title>
<Forename>J</Forename>
<Surname>Smith</Surname>
<Address1>21 Somewhere Street</Address1>
<Address2>Hereton</Address2>
<Address3>Theresville</Address3>
<Address4/>
<Address5/>
<Postcode>TH8 6AB</Postcode>
<Telephone>01234567890</Telephone>
<Email>name#provider.co.uk</Email>
</PolicyHolderClass>
I want to have some code which will get the data from the web service into a format I can use. I have created an interface
interface PHDETAILS {
Title: string,
Forename: string,
Surname: string,
Address1: string,
Address2: string,
Address3: string,
Address4: string,
Address5: string,
Postcode: string,
Telephone: string,
Email: string
}
and I have this code to retrieve the data
const phDetails: PHDETAILS = this.http.get('HelloWorld?PolicyNumber=' + policyNumber.toString());
Unfortunately this isn't working, and i'm getting this in the console
error TS2740: Type 'Observacle<Object>' is missing the following properties from type 'PHDETAILS': Title, Forename, Surname, Address1, and 7 more.
So, can anyone tell me how I get the json data into phDetails? I am using Angular 13. I would prefer a simple approach as i'm a newbie, but it can be quick and dirty as long as it gets the job done. Thanks.
Related
So i'm just starting out with typescript and something that I can't find much info on is how to deal with types for api call responses.
Lets say, I make a GET request to an api and it returns a JSON object for example:
{
name: "john",
age: 12
}
in my code, if i wanted to interact with response.name would i have to create an interface like below to use response.name without having a red linter under it?
interface Response {
name: string,
age: number
}
or is there a easier way to do it as some api calls would return JSON > 10 lines long and copying out the whole structure for every type of call seems very troublesome. Another thought I had was to create the interface but only have values I would use instead of the whole structure, but i'm not too sure so any help would be greatly appreciated!
You can define Response as a "common" type, that supports all types of API json response.
interface IResponse {
[key: string]: any
}
Now, you can type response.name without the "red line", also response.not_exist_property is valid.
My recommendation is to define all types for all API response type:
interface GetUserResponse {
name: string,
age: number,
}
for GET /users/:id (example)
You can use this tool to convert a json response to Typescript type.
Background: Project uses Yelp API in JSON to sift through business data. Two types of endpoints are use - https://www.yelp.com/developers/documentation/v3/business_search and https://www.yelp.com/developers/documentation/v3/business. The first part of this projects works as expected where the business_search api is parsed, saved as a list of strings and converted to a Business objects when it is needed to be displayed. The JSON -> Object code is as follows:
factory Business.fromJSON(Map<String, dynamic> json) {
return Business(
rating: json['rating'],
price: json['price'],
phone: json['phone'],
id: json['id'],
name: json['name'],
alias: json['alias'],
isClosed: json['is_closed'],
reviewCount: json['review_count'],
url: json['url'],
imageUrl: json['image_url'],
);
}
The code works when a call is converted from the business/search endpoint, with the JSON printout being:
json = {rating: 4.5, price: $$, phone: +16316751500, id: D5dS2-8JXhZxo3BzMLV3xQ, name: Ichi sushi & ramen, alias: ichi-sushi-and-ramen, is_closed: false, review_count: 128, url: https://www.yelp.com/biz/ichi-sushi-and-ramen?adjust_creative=Aj73ii92JG9IDLNvRyn_Ow&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=Aj73ii92JG9IDLNvRyn_Ow, image_url: https://s3-media1.fl.yelpcdn.com/bphoto/Phib_AwTkdD_kBV8r7179Q/o.jpg}
The Issue: I encounter the following exception
[VERBOSE-2:ui_dart_state.cc(166)] Unhandled Exception: FormatException: Unexpected character (at character 2)
{id: D5dS2-8JXhZxo3BzMLV3xQ, alias: ichi-sushi-and-ramen...
^
when this response from business/details is called, saved and attempted to be converted to objects:
json = {id: D5dS2-8JXhZxo3BzMLV3xQ, alias: ichi-sushi-and-ramen, name: Ichi sushi & ramen, image_url: https://s3-media1.fl.yelpcdn.com/bphoto/Phib_AwTkdD_kBV8r7179Q/o.jpg, is_claimed: true, is_closed: false, url: https://www.yelp.com/biz/ichi-sushi-and-ramen?adjust_creative=Aj73ii92JG9IDLNvRyn_Ow&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_lookup&utm_source=Aj73ii92JG9IDLNvRyn_Ow, phone: +15836751500, display_phone: (583) 675-1500, review_count: 128, categories: [{alias: sushi, title: Sushi Bars}, {alias: ramen, title: Ramen}], rating: 4.5, location: {address1: 200 Country Rd, address2: null, address3: , city: Bayshore, zip_code: 11803, country: US, state: NY, display_address: [200 Country Rd, Bayshore, NY 11803], cross_streets: }, coordinates: {latitude: 40.92842, longitude: -73.116}, photos: [https://s3-media1.fl.yelpcdn.com/bphoto/Phib_AwTkdD_kBV8r7179Q/o.jpg, https://s3-media2.fl.yelpcdn.com/bp<…> (*My note: debugger truncates with <...>*)
What is going wrong here? I have been trying many (and I mean many) different cases to rule out what the issue is but cannot find anything that is blatantly amiss. The only difference I can see is that the first type of call (business/search) starts with "rating" and contains fewer fields while the second type of call (business/details) returns much more data (note that I do not need much of it and hence do not need it in the Business object, but the nature of Yelp's api requires I do it in this way) and starts with the "id" field instead. Are these differences to blame and what does this error mean? Can you "plug in" a JSON to an object that has more fields than needed properties as I would like to keep the Business object as versatile as possible? Regardless, how could this be resolved? If more info is needed, please let me know. Thank you for your help and time!
After further analyzing the code, #KhashayarMotarjemi's suggestion tipped me off on a possible problem: the way the data was encoded. To save the data, I ran the the JSON through the toString() method, stripping the data of all of its " " and making it unable to be correctly parsed as JSON later on when retrieved from memory. The correct method would be jsonEncode(yourData) as this converts it to a string to be saved, but preserves the format needed when decoded down the line. So to anyone reading, if you are trying to store your JSON as a string, you must use jsonEncode() and not toString() when doing so. I hope this can help someone in the future!
I got a working code of siddhi and i want to know if its posible to output the events using a json format without an enclosing element.
I tried it putting a null enclosing.element and $. , but none of them seems to work.
#sink(type = 'file', file.uri = "/var/log/cert/output/{{name}}",
#map(type = 'json', fail.on.missing.attibute = "false",enclosing.element="$."))
define stream AlertStream (timestamp long, name string, ipsrc string, ipdst string, evento string, tipoAmenaza string, eventCategory string, severity string, network string, threatId string, eventTech string, eventArea string, urlOriginal string, eventID string, tag string);
i got the following result
{"event":{"timestamp":1562232334157,"name":"client_name","ipsrc":"192.168.1.1","ipdst":"192.168.1.2","evento":"threat","tipoAmenaza":"file","eventCategory":"alert","severity":"medium","network":"192.168.0.0-192.168.255.255","threatId":"spyware","eventTech":"firewall","eventArea":"fwaas","urlOriginal":"undefined","eventID":"901e1155-5407-48ce-bddb-c7469fcf5c48","tag":"[Spyware-fwaas]"}}
and the expect output is
{"timestamp":1562232334157,"name":"client_name","ipsrc":"192.168.1.1","ipdst":"192.168.1.2","evento":"threat","tipoAmenaza":"file","eventCategory":"alert","severity":"medium","network":"192.168.0.0-192.168.255.255","threatId":"spyware","eventTech":"firewall","eventArea":"fwaas","urlOriginal":"undefined","eventID":"901e1155-5407-48ce-bddb-c7469fcf5c48","tag":"[Spyware-fwaas]"}
You have to use custom mapping facilitated with #payload annotation. For more information please refer https://siddhi-io.github.io/siddhi-map-json/api/5.0.2/#json-sink-mapper
#sink(type='inMemory', topic='{{symbol}}',
#map(type='json',
#payload( """{"StockData":{"Symbol":"{{symbol}}","Price":{{price}}}""")))
define stream BarStream (symbol string, price float, volume long);
I have Login Page.
Structure as below:
FirstName:
LastName:
Address:
Street:
Contact number:
Email:
I have create Address using FormArray. I'm trying to write uni test case to check field empty in Address array.
I tried accessing the value as
let street = component.form.controls['address].get('Street'); expect(street.valid).toBeFalsy();
Showing error as
cannot read property valid of undefined
How does I deserialise data like this into a case class like this:
case class SoundCloudUser (
id: Int,
permalink: String,
username: String,
country: String,
full_name: String,
city: String,
description: String)
(that is, where the case class has less constructor arguments than the JSON has values)
I tried creating a FieldSerializer to do this, but I could only work out how to ignore fields when serialising, not deserialising.
As long as the fields in the JSON data are a superset of the fields in your case class, you don't need to do anything special to ignore the fields in the JSON data that aren't in your case class. It should "just work". Are you getting any errors?