How to get object of object in JSON API response? - json

I'm using Ionic with Angular. I have a JSON API response and I want to get the items of an object inside an object, in this case, author items.
JSON API response
{
x{
**authors**:{
auth-sara-rts-2022:
Code: "rts"
Contact:{
email:"xx#gmail.com"
phone:"0.."}
[[Prototype]]: Object
auth-sami-sgs-2022:
Code: "sgs"
Contact:{
email:"xx#gmail.com"
phone:"0.."}
[[Prototype]]: Object
[[Prototype]]: Object
}
[[Prototype]]: Object},
y{
yy: "text"
[[Prototype]]: Object}
[[Prototype]]: Object}
}
Here is how to call the API in ts file
callAPI(body: any, header: any): Observable<any> {
return this.http.post(API_URL+API_ENDPOINT,body,header);
}
postAPI(body:any,header) {
this.callAPI(body, header).subscribe(
(data) => { console.log(data.x.authors);
}
);
}
I get a list of authors, and I'd like to access the items in each author's collection (code and contact).
I tried this code, but it returned an undefined value.
console.log(data.x.authors[0]);

The issue you're having is that you are trying to use Array notation (data.x.authors[0]) to access key/value pairs in an Object. In order to transform the authors Object into an Array, there are multiple approaches. I would propose Object.entries, which returns an Array of tuples, each tuple containing the key followed by the value:
const authors = Object.entries(data.x.authors);
console.log(authors[0]); // ['auth-sara-rts-2022', { Code: 'rts', ... }]
Here are the MDN docs for Object.entries():
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries

Related

Explicit type for List in JSON-Response in REST API

Getting explicit java.util.ArrayList in JSON responses for lists
Hi,
I'm writing a REST API using Kotlin and noticed that when I'm creating a class returning a list like this:
data class TestClass( var test: List<String> = listOf() )
This is the JSON I'm getting in response, with explicit ArrayList as type:
{ test": [ "java.util.ArrayList", [] ] }
Is it possible to not get the java.util.ArrayList in the JSON response?

How do I correctly deserialize json that consists of a list item that includes another object?

The client I am using returns json like this:
[
{
"source": "ANY"
}
]
That is, the element of the array that the object is in.
I'm trying to make a request like this:
restTemplate.postForObject<AbcdResponse>(
"/address",
listOf(value).let { JsonHttpEntity(it) }
)
data class AbcdResponse(
val obj: AbcdObject
)
data class DaDataAddress(
val source: String?
)
But I get the HttpMessageNotReadableException exception:
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `com.app.client.abcd.domain.AbcdResponse` out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `com.app.client.abcd.domain.AbcdResponse` out of START_ARRAY token
at [Source: (ByteArrayInputStream); line: 1, column: 1]
How can I deserialize the response correctly?
As you probably noticed, the response as a whole is a JSON array. You can tell by the square brackets [ ... ] surrounding the whole thing.
Because of this, you cannot deserialize it as an object (such as AbcdResponse). What you should do instead is use List<DaDataAddress> instead of AbcdResponse.
You don't really need AbcdResponse. What you need is to use a ParameterizedTypeReference as follows while calling the service:
restTemplate.exchange("/address",
HttpMethod.POST,
listOf(value).let { JsonHttpEntity(it) },
ParameterizedTypeReference<List<DaDataAddress>>() {})
The reason is that the service that you are calling is returning a JSON array of JSON objects.

Not able to get value from Json key

I am trying to get an object from Mongoose but when I get it and try to access the Json object by key to get the value i get undefined.
User.find({name: 'auth'},function (err,obj) {
var authCode = JSON.stringify(obj);
console.log(authCode);
var parse = JSON.parse(authCode);
console.log(parse);
console.log(parse.code);
});
I get the following output:
[{"_id":"5a43b491734d1d45eaf2d00d","name":"auth","code":"nCAxOSrUMqxtxd8T"}]
[ { _id: '5a43b491734d1d45eaf2d00d',
name: 'auth',
code: 'nCAxOSrUMqxtxd8T' } ]
undefined
I have even tried console.log(parse['code'])and i still get undefined. Can someone please help me
parse variable above is not a dictionary itself, but an array containing a dictionary. What you should do to access the code field would be first access the dictionary and then get the code field like;
parse[0].code
or
parse[0]['code']
You need not parse or stringify the returned JSON object. You can use the JSON object as it is. Try below approach
User.find({name: 'auth'},function (err,obj) {
console.log(obj);
console.log(obj.code);// this will probably be undefined as find method returns array of objects ( correct me if iam wrong)
user.forEach(function(obj,index){
console.log("index: "+index);
console.log("obj: "+obj.code);
});
});
Using promises is a good way
User.find({name: 'auth'})
.then((user)=>{
console.log("find success");
console.log(user);
console.log(user.code); // would return undefined as User.find will return array of objects
user.forEach(function(obj,index){
console.log("index: "+index);
console.log("obj: "+obj.code);
});
})
.catch(()=> {
console.log("find failed");
});

Json manipulation TypeScript Angular 2

I come from a Python Background and recently started programming using TypeScript and Angular2. I want to know how to obtain keys from a JSON object using TypeScript.
I have a response like so:
response.text()
I pass this object to a function
removeMetaData (my_data: string){
//(Various manipulation)...etc
}
i have read that I can call a json() method instead of text(). If I do that, what is the type I should use for my_data?
Then,
If my JSON looks like this:
{
"count": 100,
"next_page": "http://www.test.com/users/?page=2",
"prev_page": "http://www.test.com/users/?page=3",
"results":[
{
"username": "johnny"
},
Etc....
]
How do I parse that?
I've read I might have to use an interface but I don't understand how.
In python it's just response["next_page"] to get the key of a dictionary, then I can assign that value to a variable within the class. That is exactly what I'm trying to achieve within a component.
Thank you.
ADDITION
list() {
this.requestService.get(this.api_path)
.subscribe(
response => this.populate(response.json()),
error => this.response = error.text()
)
}
populate(payload: object) {
this.count = payload.count;
this.next = payload.next;
this.previous = payload.previous;
*payload.results => this.users = payload.results;******
}
Declare an interface which will be used as value object.
export interface IPage
{
count:number;
next_page:string;
prev_page:string;
results:Array<any>;
...
...
}
var my_data:IPage;
Now assign parsed json value to my_data and access all the properties with '.' operator i.e. my_data.count, my_data.results.
Feel free to throw any question.
If I do that, what is the type I should use for my_data?
Its just a javascript object.
As an example if you json looks like:
{
"foo": {
"bar": "bas"
}
}
Then in the parsed json (in variable someObj) the value someObj.foo.bar would be bas 🌹

How can you use GWT AutoBeans to parse a JSON message when some of the return values could be an object or a collection of objects?

Is it possible to parse a JSON message using GWT AutoBeans when one of the objects returned may be a collection but not always?
For example, if I have a JSON message returning an author and his/her associated writings, it's possible that there could be zero or more books being returned.
{ "name" : "William Gibson", "books" : { bookname : "Neuromancer" } }
could be one response, but so could this:
{ "name" : "William Gibson", "books" : [ { bookname: "Neuromancer"}, { bookname : "Pattern Recognition" } ] }
When I attempt to model this with an interface to be used for marshalling with an AutoBean, I get "expecting indexed data" errors if only one book is returned.
Interface for the AutoBean:
public interface Author {
#PropertyName(value="name")
String getAuthorName();
#PropertyName(value="book")
List<String> getBooks();
}
Snippet of error:
java.lang.AssertionError: Expecting indexed data
at com.google.web.bindery.autobean.shared.impl.SplittableList.<init>(SplittableList.java:64)
Is this not possible with AutoBeans?
(Note: using GWT 2.5.0 GA)
If you have a List, AutoBeans expects a JSON array. That array could contain zero, one or more elements, but it has to be an array (or be absent).
I think you can make your getBooks method return a Splittable though. You could then know whether it's an array (isIndexed()) or not. If you need the array to contain objects, you'd then have to iterate on the array (size() and get(int)) and pass each element to AutoBeanCodex.decode() to decode them (or directly pass the splittable if it's not an array).