I have an API (/js/feed/sms.json
) that returns data that looks like this:
[
{
id: 1,
name: "Test feeds 1",
headline: "Here is a headline",
feed-url: "/something?q=1"
},
{
id: 2,
name: "Test feeds 2",
headline: "Here is another headline",
feed-url: "/something?q=2"
},
{
id: 3,
name: "Test feeds 3",
headline: "Here is a third headline",
feed-url: "/something?q=3"
}
]
I have a couple of React components.
The first is a call to an API: fetch-api-data.jsx:
import * as axios from 'axios';
export default class FetchApiData {
constructor() {
console.log('FetchAPIData loaded');
}
static shareMyStoryData(URL) {
return axios.get(URL)
.then(function (response) {
})
.catch(function (error) {
console.log(error);
});
}
}
The second is a component that parses the data.
import * as React from 'react';
import * as DOM from 'react-dom';
import PropTypes from 'prop-types';
import axios from 'axios';
import './share-my-story.scss';
import FetchApiData from './fetch-api-data';
class ShareMyStory extends React.Component {
constructor(props) {
super(props);
this.state = {
smsData: ''
}
}
componentDidMount() {
const URL = '/js/feed/sms.json';
FetchApiData
.shareMyStoryData(URL)
.then((response) => {
this.setState({smsData: response });
})
.catch((error) => {
console.log(error);
});
}
render() {
console.log(this.state.smsData);
return (
<div>
<h1>{this.state.smsData.name}<h1>
<h2>{this.state.smsData.headline}</h2>
<h3><a href={this.state.smsData.link}>{this.state.smsData.link}</a></h3>
</div>
);
}
}
ShareMyStory.propTypes = {
name: PropTypes.string,
headline: PropTypes.string,
link: PropTypes.string,
smsData: PropTypes.array
}
DOM.render(
<ShareMyStory/>, document.getElementById('share-my-story'));
I'm having 2 problems:
First is that I'm getting undefined in my console.log of the this.state.smsData
.
Second, I need to loop thru that object and output the items in the return. I'm coming from Angular, so I'm familiar with their iterative ng-repeat
, but I don't see a similar tool in React. Is there a preferred way to do this?
If you really have that empty .then(function(response){})
in your FetchApiData, then that is the problem. Either add { return response } there (useless, but at least then it should work) OR remove that .then
.
For your second question, as pointed out by others: In React you use the .map
method of an array to iterate an array:
{ this.state.smsData.map(data => <div>...</div>) }
Some points: if your smsData is (or will be) an array, then it's better to initialise it with either undefined
or an empty array. I would advise undefined
, so you can make the distinction between A) there is no data yet, and B. The data has been fetched, but there are no records (i.e. smsData.length === 0
)
In your component you can then check whether to render the data, a loading indicator, or some message that there are no records, something like:
render() {
const { smsData } = this.state;
if (!smsData) { return <div>Loading...</div>; }
if (smsData) {
if (smsData.length === 0) { return <div>No data</div>; }
return smsData.map(data => <div>...</div>);
}
}