I am trying to get a JSON object API from server and my json start with objects and l am not familiar with Json response start with objects immediately .
Json url
{
"ABQ": {
"airport": {
"name": "Albuquerque International Airport",
"code": {
"iata": "ABQ",
"icao": "KABQ"
}
}
},
"ACE": {
"airport": {
"name": "Lanzarote Airport",
"code": {
"iata": "ACE",
"icao": "GCRR"
}
}
},
"ADB": {
"airport": {
"name": "Izmir Adnan Menderes International Airport",
"code": {
"iata": "ADB",
"icao": "LTBJ"
}
}
}
}
My code :
Data :any
getData(){
this.http.get("xxxxxxxx/", {}, {}).then(data =>{
this.Data = JSON.parse(data.data)
console.log(this.Data)
})
}
HTML
<div class="ion-padding">
{{Data.airport.name}}
</div>
l got error
ERROR TypeError: Cannot read property 'airport' of undefined at object.eval
how can l get the data json response ?
You have two problems in your example:
You're trying to render the data before it was loaded. And as long as you're trying to get user attributes you get exceptions like Cannot read property XXX of undefined
You are ignoring intermediate properties of your data object.
There is more than one way to skin a cat and there are several possible solutions. One of them I've implemented in this example https://stackblitz.com/edit/angular-zuqbry.
I'm using async filter to wait for the server response to be resolved
<p *ngFor="let item of data | async">
{{item.airport.name}}
</p>
I'm iterating over Object keys in order to get all there 'dynamic keys' and fetch data from the data object
this.data = http.get()
.pipe(
map(response => {
const keys = Object.keys(response);
return keys.map(key => response[key]);
})
);
Please, note that http is an object of CustomHttpService that I've created to provide data from hardcoded file, however it works very similar to original HttpClient.
Related
I'm using React to create a web application. I have a DynamoDB table in AWS and an AppSync API configured.
I'm using the following to make an api call:
const [items, setItems] = useState([]);
useEffect(() => {
(async () => {
const apiGroups = await API.graphql(graphqlOperation(queries.getNtig, { PK: "Status", SK: "Active" }));
setItems(apiGroups.data.getNtig.Group);
})();
}, []);
Later on I use the results to create a dropdown. I had this working perfectly with Rest but I'm trying to switch to using GraphQL.
I see the JSON response in the webconsole:
{
"data": {
"getNTIG": {
"PK": "Status",
"SK": "Active",
"Group": [
"Group1",
"Group2"
]
}
}
}
I always get Unhandled Rejection (TypeError): apiGroups.data.getNtig is undefined
Any help greatly appreciated.
The problem is that the key you are referring to is named getNTIG and not getNtig. The language is case sensitive so it is important to use the right case.
I'm fetching API data using AngularJS/Ionic 2. I've followed this guide and get it to properly log the data when I go to home.html. But when I try to actually display the data in home.html I can't get it to work.
data-provider.ts:
getRemoteData(){
this.http.get('https://api.example.com/?limit=10').map(res => res.json()).subscribe(data => {
console.log(data);
});
}
home.ts:
ionViewDidLoad(){
this.dataService.getRemoteData();
}
This correctly logs JSON data:
[
{
"id": "a",
"name": "ExampleA",
"price": "10"
},
{
"id": "b",
"name": "ExampleB",
"price": "15"
}
]
I've tried returning the data instead of logging the data, then creating a variable data: any; in the home.ts and outputting the data in home.html as <p> data[0].name </p> but I kept getting the error message, Can't read property '0' of undefined
Two point: you have either to assign the value from the request to a component's property and in the template wait for this property to be assigned.
Your service/provider should be (only):
getRemoteData(){
return this.http.get('https://api.example.com/?limit=10')
.map(res => res.json());
}
you shouldn't subscribe to the observable in it. Do this in the component:
ionViewDidLoad(){
this.dataService.getRemoteData().subcribe( response => this.data = response);
}
in the template, as mentioned before, check if the 'data' exists:
<p *ngIf="data">data[0].name </p>
With the help of the forum I was able to get my httpclient observable mapping issue sorted with this syntax;
this._http.get<DomainMetaData>(serviceURL);
which works great! However, I have a json response coming back from the server which is nested and wonder if I can use the same syntax as I'm currently using or if I need to now manually .map the response into my classes?
Based on posts I've seen here on SO I've created two classes to represent the nested structure of the response JSON (see below).
The function call...
getDomainMetaData(domain): Observable<DomainMetaData> {
let serviceURL = "http://localhost:3000/selectdomains?domain=" + domain;
return this._http.get<DomainMetaData>(serviceURL);
}
The classes...
export class DomainMetaDataAttr {
constructor(public name: string,
public value: string) {
}
}
export class DomainMetaData {
constructor(public name: string,
public attributes: DomainMetaDataAttr[]) {
}
}
An example of the json...
//DomainMetaData
// {
// "ResponseMetadata": {
// "RequestId": "11f000bf-0dff-8a2a-31ff-8631a9f25b5b",
// "BoxUsage": "0.0008183545"
// },
// "Items": [
// {
// "Name": "2",
// "Attributes": [
// {
// "Name": "Document Date",
// "Value": "22/03/13"
// },
// {
// "Name": "Document Ref",
// "Value": "Doc test"
// }
// ]
// },
I love the neatness and simplicity of my current solution but I appreciate I may now have to change my code!
Many Thanks.
If I understand correctly you want to know how to use the JSON response from an HttpClient call.
I currently approach it like this:
// x.service.ts
getData() {
return this.http.get(URL);
}
// x.component.ts
this.service.getData().subscribe(res => {
if (res['data']) {
const data = res['data'];
// do whatever with the data
}
});
With the above approach you can run whatever methods / filters you want on the JSON e.g. map over the array and pull data out / mutate it, etc. Not sure if it's necessary to create additional classes to deal with the nested JSON data.
Oops! The code I posted actually works, I just wasn't referencing the results in the attributes array correctly.
Thanks for taking the time to look at this.
In my Angular RC2 app I make an observable HTTP call that returns the following JSON to me from the API:
{
"success":true,
"data":
{
"Type": 1
"Details":{
"Id":"123",
"Name":"test",
"Description":"test"
}
}
}
I map the data like this:
this._myService.get(id)
.subscribe(
(data) => {
this.details = data.Details;
this.type = data.Type;
},
(error) => {
this.setError(error);
}
);
How do I access the values inside the "Details" object from here?
I tried:
{{details.Name}}
But that won't work and I can't use ngFor to loop it either.
You could use the Elvis operator for this:
{{details?.Name}}
As a matter of fact, you load your data asynchronously so details is undefined at the beginning.
I am trying to access properties of the following JSON structure through AngularJS factory and service methods:
{
"#context": {
"firstname": "http://xmlns.com/foaf/0.1/firstname",
"lastname": "http://xmlns.com/foaf/0.1/lastname"
},
"members":[
{
"firstname":"Debjit",
"lastname":"Kumar"
},
{
"firstname":"Hari",
"lastname":"Haran"
},
{
"firstname":"Kaushik",
"lastname":"Shrestha"
}
]
}
But I am not able retrieve properties of the retrieved JSON object.
The following is my angularJS code:
angular.module('rdfa',['ngResource']).config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/', {controller: RdfaCtrl});
}])
.factory('members', function($resource){
return $resource('Json.json', {}, { query: {method:'GET', isArray:false} } );
})
.service('jsonservice',function(members){
this.members=members.query();
});
function RdfaCtrl($scope,jsonservice){
$scope.members=jsonservice.members.members;
console.log(jsonservice.members); // outputs correct JSON structure
console.log(jsonservice.members.members); // outputs undefined
console.log(jsonservice.members['#context']); // outputs undefined
}
You are making an asynchronous HTTP request, you cannot just simply print the output on the same call cycle. In order to do that you need to add a success callback handler in the query action, for example:
members.query(function(value) {
console.log(value); // Resource object
console.log(value.members); // members object
console.log(value['#context']); // #context object
});
Check this plunker for a working example: http://plnkr.co/edit/TFlQ6cDkIA3rpjkvHtOA?p=preview