Angular 2: Access object data - json

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.

Related

Change JSON structure to send in API post request

I am making an API POST call in Angular 8. I have to send a JSON object in the call which should be of structure:
-{}JSON
-{}data
-[]exp
+{} 0
+{} 1
but I am sending data in this format:
-[]JSON
+{} 0
+{} 1
in my typescript I am getting two objects {}0, {}1 in array called: receivedData then I am storing the data like:
this.changedData = this.receivedData;
this.postService.postMethod(this.headers, this.changedData)
in my postService:
postMethod(header, changedData): Observable<any[]> {
return this.http.post<any>(`the url here`, changedData, {headers: header, responseType: 'text' as 'json'})
.pipe(map(response => {
return response;
}))
}
how to send data in the mentioned format? I want the json structure of changedDetails to be as mentioned on the top with the same naming convention like: {}data and []exp How can I push receivedData objects into exp[] which I can then send into data{} which will then be entirely pushed into changedDetails {}
Just so we're on the same page, I'm imagining you're receiving data with the following shape:
[ { ... }, { ... } ]
And you want to transform it to this shape:
{
data: {
exp: [ { ... }, { ... } ]
}
}
(Let me know if this is not the case.)
If this is correct, than the transformation is quite straightfoward: simply create a new object literal like so:
this.changedData = {
data: {
exp: this.receivedData,
},
};

Get json objects from server

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.

Data from API is displaying in the console but not in the DOM, why?

I'm learning React and a little about API's. I'm using the Destiny 2 API as a starting API to try to wrap my head around how they work.
Here is my Api.js file:
import React, { Component } from 'react';
import './style.css';
import axios from 'axios';
class Api extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
};
}
componentDidMount() {
let config = {
headers: {
'X-API-KEY': 'key-here',
},
};
axios
.get('https://www.bungie.net/Platform/Destiny2/4/Profile/4611686018484544046/?components=100', config)
.then((response) => {
console.log(response);
this.setState({
data: response.data,
});
});
}
render() {
const { item } = this.state;
return (
<div>
{Array.isArray(item) &&
item.map((object) => <p key={object.data}>{object.data.Response.profile.data.userInfo.displayName}</p>)}
</div>
);
}
}
export default Api;
The data from the API is returned as an object that contains a nested array. I can get the data to display in the console no problem.
This is the layout of the response object output to the console:
I'm trying to grab the value of "displayName" and output it into the DOM, what am I doing wrong?
I have tried returning the data as JSON by doing:
response => {return(data.json())} and iterating through the json object using {Object.keys(this.state.data).map((key) => but I have still managed to only get data in the console and not in the DOM.
Is there anything that seems to be missing? I've been stuck with this problem for several days now!
EDIT: This is the whole response from the API call
{
"Response": {
"profile": {
"data": {
"userInfo": {
"membershipType": 4,
"membershipId": "4611686018484544046",
"displayName": "Snizzy"
},
"dateLastPlayed": "2019-04-05T14:28:30Z",
"versionsOwned": 31,
"characterIds": [
"2305843009409505097",
"2305843009411764917",
"2305843009425764024"
]
},
"privacy": 1
}
},
"ErrorCode": 1,
"ThrottleSeconds": 0,
"ErrorStatus": "Success",
"Message": "Ok",
"MessageData": {}
}
In the render function, where you destructure you state, you have the wrong property.
const { item } = this.state; should be const { data } = this.state;
More about destructuring here.
Also, you need to make changes here:
EDIT: Actually, your data isn't even an array. You don't have to iterate through it.
<div>
<p>{data.Response.profile.data.userInfo.displayName}</p>}
</div>
Let's do a check to make sure that we got back the api before running. You might be rendering before the api call is finished. Try using an inline statement.
{ item ? {Array.isArray(item) && item.map(object => (
<p key={object.data}>{object.data.Response.profile.data.userInfo.displayName}</p>
))}
:
<div>Loading...</div>

Display JSON data with Ionic 2/AngluarJS?

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>

Unable to access properties of JSON code through angularJS service

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