React grabbing JSON response property - javascript

I'm very new to React. I have a JSON response that is being returned to me VIA WebAPI 2.
I would like to display only parts of this reply, for example if i only want to display the title
I have implemented the following code, but when view title it shows up as undefined
App.js
class App extends React.Component {
constructor(props){
super(props);
this.state = {reply: ""}
this.callAPI = this.callAPI.bind(this);
}
componentDidMount(){
this.callAPI();
}
callAPI(){
fetch('http://localhost:51092/api/COM',{
method:'get',
headers:{'Content-Type':'application/json'}
}).then(function(response){
return response.json();
}).then(responseData => {
this.setState({reply:responseData});
console.log("REPONSEDATA-----"+responseData);
console.log(responseData.title);
});
}
render(){
return(
<div>
</div>
);
}
}
Update 1
callAPI(){
fetch('http://localhost:51092/api/COM',{
method:'get',
headers:{'Content-Type':'application/json'}
}).then(response =>{
return response.json().then(responseData => {
this.setState({reply:responseData});
console.log("RESPONSE----"+JSON.stringify(responseData));
console.log(responseData.title);
});
});
}
API JSON Response
[{
"fileVer": {
"type": "specific",
"fileId": {
"type": "specific",
"internalId": 1,
"externalId": null
},
"internalVersion": 2,
"externalVersion": null,
"versionSortKey": "0"
},
"title": "1576544 Alberta Ltd._Annual Returns_2012-01-03",
"extension": "pdf",
"logicalSize": "47872",
"sizePrecision": "exact",
"createdAtUtc": "2019-05-27T15:22:41.510Z",
"lastAccessedAtUtc": "2019-07-10T21:00:28.029Z",
"lastWrittenAtUtc": "2019-05-27T15:17:48.000Z",
"changedAtUtc": "2019-05-27T15:17:48.000Z",
"fileGuid": "{881D8975-84B9-4A73-9AFF-F0C61C94FE90}",
"checksumMD5": "24f6badff8b70783697e0052fc4a7fe6",
"fileMissing": false,
"contentIsVolatile": false
}][{
"fileVer": {
"type": "specific",
"fileId": {
"type": "specific",
"internalId": 2,
"externalId": null
},
"internalVersion": 3,
"externalVersion": null,
"versionSortKey": "0"
},
"title": "1576544 Alberta Ltd._By-Law #1_",
"extension": "pdf",
"logicalSize": "951046",
"sizePrecision": "exact",
"createdAtUtc": "2019-05-27T15:22:42.000Z",
"lastAccessedAtUtc": "2019-07-10T21:02:54.062Z",
"lastWrittenAtUtc": "2019-05-27T15:16:28.000Z",
"changedAtUtc": "2019-05-27T15:16:28.000Z",
"fileGuid": "{F8B54DB0-7E9F-4F0F-8ABA-D03C1DE4FF8C}",
"checksumMD5": "ffe728ef1a87f0cec7737b6d224bb50d",
"fileMissing": false,
"contentIsVolatile": false
}]
Not sure what im doing wrong here, ive used Ajax a lot so maybe im confusing what can be done with react and fetch
Update 2
So it seems that this may be a single object, and not an array of objects.
console.log("RESPONSE----"+JSON.stringify(responseData));
var arr = [];
console.log("KEYS"+Object.keys(responseData));
Object.keys(responseData).forEach(function(key){
console.log(responseData[key]);
arr.push(responseData[key]);
When i try to access responseData[key] i end up getting a single letter, and not a property from the json response
This pushes me to believe that this is not an array of objects but a single object

you should use JSON.stringify when printing full json response and if part of the object is string (eg... response.title then its ok but if not you can try .toString() or JSON.stringify)
callAPI(){
fetch('http://localhost:51092/api/COM',{
method:'get',
headers:{'Content-Type':'application/json'}
}).then(function(response){
return response.json().then((responseData)=>{
this.setState({reply:responseData});
console.log("REPONSEDATA----"+JSON.stringify(responseData));
console.log(responseData.title);
return responseData
});
}

Related

how to access obj from json in React?

Api Respose :-
[
{
"System Name": "Name1",
"Primary Sensor": "WWWW",
"Mean Wind Speed": "6.23 m/s",
"Status": 1,
"mws_number": 44,
"DRR (%)": "100",
"drr_number": 100
},
{
"System Name": "Name 2",
"Primary Sensor": "SSSS",
"Mean Wind Speed": "4.2 m/s",
"Status": 2,
"mws_number": 6,
"DRR (%)": "100",
"drr_number": 100
}
]
My Code ->
class Home extends Component {
state = {
items:[],
isLoading:false
}
componentDidMount() {
// api
fetch('http://api.url', {
method: 'POST',
body:
JSON.stringify({"Authentication":'token'})
}).then(data => data.json() )
.then(res =>{
this.setState({isLoading:true,
items:res,}
)
});
}
render() {
return (
<>
{console.log(this.state.items[0])} // getting o/p - first obj of array
{console.log(this.state.items[0].Status)} // getting Error undef Status
{console.log(this.state.items.Status[0])} // same error undef status
</>
)
export def ....
This is my complete piece of code... I can't add api url as it is not public api :(
I want to access this data inside of the array =>(Status, System Name, etc)
how can i fetch this !!
Here, console.log(this.state.items[0]); is getting called two times;
- When the page first loads and API request is not finished.
- After the API request finishes and you call this.setState
Solution would be to check that items' length is greater than 0 before trying to use it. Try changing console.log(this.state.items[0]); to this:
if (this.state.items.length > 0) { console.log(this.state.items[0].Status); }
I would suggest you to use componentWillMount() instead of componentDidMount() becuase componentWillMount() happens before render while componentDidMount() happens after the first render.May be that help.

TypeError: Cannot read property 'url' of undefined react strapi in JSON object

I'm using strapi with react. I'm fetching a JSON object (home). If I do console.log(home) I get:
{
"id": 6,
"created_at": "2020-06-21T07:07:36.000Z",
"updated_at": "2020-06-21T07:18:40.000Z",
"HomeTextTop": "Home text here.",
"HomeTitle": "Home title here",
"Hero": {
"id": 3,
"name": "facade_pastel_summer_123664_800x600",
"alternativeText": "",
"caption": "",
"width": 800,
"height": 600,
"url": "http://someurlhere.com"
}
}
If I console.log(home.Hero) I get the appropriate:
{
"id": 3,
"name": "facade_pastel_summer_123664_800x600",
"alternativeText": "",
"caption": "",
"width": 800,
"height": 600,
"url": "http://someurlhere.com"
}
However, if I drill down and try and get just the URL console.log(home.Hero.url) I get this error:
TypeError: Cannot read property 'url' of undefined react strapi in JSON object
What am I missing here?
The 'action' fetching code is:
export const fetchHome = () => {
return dispatch => {
dispatch(fetchHomeBegin())
return fetch(`${strapiUrl}/home`, {
method: 'get',
mode: 'cors',
headers: { 'Content-Type': 'application/json' }
})
.then(res => res.json())
.then(json => {
console.log(json)
dispatch(fetchHomeSuccess(json))
})
.catch(error => dispatch(fetchHomeFail(error)))
}}
And JSON.stringify(home.Hero) gives the same result in string form
Here's what's happening.
This is likely because at the moment of reading url from Hero, Hero is
not yet defined (as the error message suggests). You could tackle this
by first confirming Hero is defined before reading url. Something like
this: console.log(home.Hero && home.Hero.url).
Though this leads to a lot of cumbersome code, and therefor (imo) it
would be better to use https://www.npmjs.com/package/immutable to
manage the data that is returned from the Strapi api.
You would then set home as an immutable object (a Map) and read url
like this: console.log(home.getIn([‘Hero’, ‘url’]). If Hero is
undefined here your application will not crash, but instead false will
be returned. - Boaz Poolman - slack.strapi

Can I use a state value to reference a value inside of a lookup table that is stored locally in my project?

I have an API response that contains an item hash. I want to be able to cross reference that item hash with a lookup table that is stored locally in my project, so I am able to display a name and icon path of the item that matches the hash.
I have tried storing the item hash in state and tried to reference it in my render function like so const weaponURL = hashdata[{weapon}.displayProperties.icon];. I'm getting an error saying the Cannot read property 'icon' of undefined.
I have also tried to reference the icon path using this code in render {baseURL + {weapon && hashdata[weapon].displayProperties.icon}} but I get an error from my IDE to say that : is expected
Here is my entire JS file:
import React, {Component} from 'react';
import hashdata from '../data/data';
import ReactTooltip from 'react-tooltip';
import apiKey from '../data/apiKey';
class XUR extends Component {
state = {
isLoading: false,
error: null,
xurInventory: null,
weapon: null,
gear1: null,
gear2: null,
gear3: null
};
async componentDidMount() {
this.setState({
isLoading: true
});
try {
const xurFetch = await fetch('https://www.bungie.net/Platform/Destiny2/Vendors/?components=402', {
headers: {
'X-API-KEY': apiKey
}
});
if (!xurFetch.ok) {
throw Error(xurFetch.statusText);
}
const xurInvJson = await xurFetch.json();
this.setState({
xurInventory: xurInvJson,
weapon: xurInvJson.Response.sales.items.data[2190858386].saleItems[54].itemHash,
isLoading: false
});
} catch (error) {
this.setState({error: true});
}
}
render() {
const {isLoading, error, weapon} = this.state;
const baseURL = 'https://www.bungie.net';
const weaponURL = hashdata[{weapon}.displayProperties.icon];
if (isLoading) {
return (
<div>
<p>LOADING</p>
</div>
)
}
if (error) {
return(
<div>
<p>Error</p>
</div>
)
}
return (
<div>
<div className={"row justify-content-center"}>
<div className={"col-6 text-center py-2"}>
<img alt="icon" src={baseURL + {weapon && hashdata[weapon].displayProperties.icon}}/>
<ReactTooltip/>
</div>
</div>
</div>
)
}
}
export default XUR;
Here is a snippet from my data hash file:
const hashdata = {
"31953744": {
"displayProperties": {
"description": "",
"name": "Holy Ground",
"icon": "/common/destiny2_content/icons/d76ab9a89d00451c6a0c1d779a3e5f98.jpg",
"hasIcon": true
},
"scope": 1,
"sourceString": "Source: Complete activities and earn rank-up packages on Io.",
"sourceHash": 315474873,
"itemHash": 31953744,
"acquisitionInfo": {
"runOnlyAcquisitionRewardSite": false
},
"stateInfo": {
"requirements": {
"entitlementUnavailableMessage": ""
},
},
"presentationInfo": {
"presentationNodeType": 1,
"parentPresentationNodeHashes": [
631010939
],
"displayStyle": 3
},
"hash": 259147463,
"index": 2171,
"redacted": false,
"blacklisted": false
},
"31953747": {
"displayProperties": {
"description": "",
"name": "Ballet Lover",
"icon": "/common/destiny2_content/icons/c89eb559068c19f8ed62d56a47f33cfa.jpg",
"hasIcon": true
},
"scope": 1,
"sourceString": "Source: Complete activities and earn rank-up packages on Io.",
"sourceHash": 315474873,
"itemHash": 31953747,
"acquisitionInfo": {
"runOnlyAcquisitionRewardSite": false
},
"stateInfo": {
"requirements": {
"entitlementUnavailableMessage": ""
},
},
"presentationInfo": {
"presentationNodeType": 1,
"parentPresentationNodeHashes": [
631010939
],
"displayStyle": 3
},
"hash": 259147462,
"index": 2170,
"redacted": false,
"blacklisted": false
},
"32806262": {
"displayProperties": {
"description": "\"Our mysterious defender slew a Kell today. Kandak has banned other Risen and put a bounty on the so-called Red Moon Phantom's head.\" —Annals of the Saharan Contested Zone",
"name": "Cloak of Five Full Moons",
"icon": "/common/destiny2_content/icons/8e0e7dfa87d5c68262b6027cd22efd40.jpg",
"hasIcon": true
},
"scope": 1,
"sourceString": "Source: Open Legendary engrams and earn faction rank-up packages.",
"sourceHash": 3334812276,
"itemHash": 32806262,
"acquisitionInfo": {
"runOnlyAcquisitionRewardSite": false
},
"stateInfo": {
"requirements": {
"entitlementUnavailableMessage": "Requires Destiny 2: Forsaken"
},
},
"presentationInfo": {
"presentationNodeType": 2,
"parentPresentationNodeHashes": [
3988275539
],
"displayStyle": 3
},
"hash": 39866533,
"index": 510,
"redacted": false,
"blacklisted": false
}
}
Is anyone able to tell me where I'm going wrong? Is it possible to reference the hash table this way or will I have to store the state hash value in a variable and then reference that variable when making my call to the hash table?
I am using ReactJS.
EDIT:
I'm trying to call the icon path and place it behind a base URL in the renders img tag, so I can show the icon of specific items. I have managed to get this working using localStorage and storing the value of the hash but I was wondering if it's possible without using localStorage as the code was incredibly messy and it seemed like a long winded way of doing things, especially when I was having to create localStorage items for many items at a time.

Programmatically create Gatsby pages from Contentful data

I am looking for help with GatsbyJS and Contentful. The docs aren't quite giving me enough info.
I am looking to programmatically create pages based on contentful data. In this case, the data type is a retail "Store" with a gatsby page at /retail_store_name
The index.js for each store is basically a couple of react components with props passed in e.g. shop name and google place ID.
Add data to contentful. Here is my example data model:
{
"name": "Store"
"displayField": "shopName",
"fields": [
{
"id": "shopName",
"name": "Shop Name",
"type": "Symbol",
"localized": false,
"required": true,
"validations": [
{
"unique": true
}
],
"disabled": false,
"omitted": false
},
{
"id": "placeId",
"name": "Place ID",
"type": "Symbol",
"localized": false,
"required": true,
"validations": [
{
"unique": true
}
],
"disabled": false,
"omitted": false
}
}
I've added the contentful site data to gatsby-config.js
// In gatsby-config.js
plugins: [
{
resolve: `gatsby-source-contentful`,
options: {
spaceId: `your_space_id`,
accessToken: `your_access_token`
},
},
];
Query contentful - I'm not sure where this should happen. I've got a template file that would be the model for each store webpage created from contentful data.
As mentioned this is just some components with props passed in. Example:
import React, { Component } from "react";
export default class IndexPage extends Component {
constructor(props) {
super(props);
this.state = {
placeId: "",
shopName: "",
};
}
render (){
return (
<ComponentExampleOne shopName={this.state.shopName} />
<ComponentExampleTwo placeId={this.state.placeId} />
);
}
I'm really not sure how to go about this. The end goal is auto publishing for non-tech users, who post new stores in Contentful to be updated on the production site.
You can create pages dynamically at build time and to do that you need to add some logic to the gatsby-node.js file. Here is a simple snippet.
const path = require('path')
exports.createPages = ({graphql, boundActionCreators}) => {
const {createPage} = boundActionCreators
return new Promise((resolve, reject) => {
const storeTemplate = path.resolve('src/templates/store.js')
resolve(
graphql(`
{
allContentfulStore (limit:100) {
edges {
node {
id
name
slug
}
}
}
}
`).then((result) => {
if (result.errors) {
reject(result.errors)
}
result.data.allContentfulStore.edges.forEach((edge) => {
createPage ({
path: edge.node.slug,
component: storeTemplate,
context: {
slug: edge.node.slug
}
})
})
return
})
)
})
}
the createPages that was exported is a Gatsby Node API function you can find the complete list in the docs here.
For the query allContentfulStore it's called like that because your contentType name is store the gatsby query will be allContentful{ContentTypeName}.
Finally, I created a youtube video series explaining how you can build a Gatsby website with Contentful. You can find it here
I hope this answer your question.
Cheers,
Khaled

Operating on JSON returned from http.get in Angular 4.3

In my my, I am attempting to serve dynamic form controls via JSON to a form builder similar to the dynamic forms tutorial at angular.io. I am having trouble operating on JSON data returned from an http.get() request. I can console.log the whole object, but if I try to log a sub-object, I get "undefined" in the console.
Here is my component file:
export class TestComponent implements OnInit {
dataSource: Observable<any>;
questions: QuestionBase<any>[] = [];
results: QuestionBase<any>[] = [];
constructor(private http: HttpClient) {
this.dataSource = this.http.get('/questions');
}
ngOnInit() {
this.dataSource.subscribe(
data => {
this.results = data['contactInfo'];
console.log(this.results[0].controlType);
this.results.forEach((item: QuestionBase<any>) => {
if(item.controlType == 'text') {
console.log(item.controlType);
this.questions.push(new TextQuestion(item));
}
else if(item.controlType == 'dropdown') {
console.log(item.controlType);
this.questions.push(new DropdownQuestion(item));
}
});
console.log(this.questions);
},
err => {
console.log("Cannot get JSON data. Error Code: %s, URL: %s",
err.status, err.url)
},
() => console.log('Done')
);
}
}
In the data => {} callback, if I console.log(request), the console displays the entire object just fine. I can even read sub-objects in the template. But, if I try to console.log or do any other thing with sub-objects as in the code above, e.g. the forEach() method, I get "undefined" on the console. What am I doing wrong?
Edit: Here is the JSON snippet:
{
"contactInfo": [
{
"key": "firstName",
"globalLabel": "First Name",
"controlType": "text",
"required": "true",
"order": "1"
},
{
"key": "lastName",
"globalLabel": "Last Name",
"controlType": "text",
"required": "true",
"order": "2"
},
{
"key": "streetAddress",
"globalLabel": "Street Address",
"controlType": "text",
"required": "true",
"order": "3"
}, ...}]
Edit #2 I had failed to restart my Node server after updating the JSON file to read "controlType" over an earlier version that used simply "type." I figured the server would automatically serve the newly edited and saved file, but it seems as though one must restart the server in order to do this. ISSUE CLOSED

Categories

Resources