I am trying to print data from fetched JSON but somehow i am unable to do it.
interface IFetched {
fetchedData: any;
error: any;
}
export default class Testing100 extends React.Component<
ITesting100Props,
IFetched,
{}
> {
constructor(props: ITesting100Props) {
super(props);
this.state = {
error: null,
fetchedData: [],
};
}
public componentDidMount() {
fetch("https://api.randomuser.me/")
.then((res) => res.json())
.then(
(result) => {
this.setState({
fetchedData: result,
});
},
(error) => {
this.setState({
error,
});
}
);
}
public render(): React.ReactElement<ITesting100Props> {
console.log(this.state.fetchedData.results);
return (
<div>
<a>
{this.state.fetchedData.map(function (fetchedDataX) {
return fetchedDataX.results[0].name.first;
})}
</a>
</div>
);
}
}
With console log i am able to print data. But when i change console log from console.log(this.state.fetchedData.results);
to console.log(this.state.fetchedData.results[0]);
i get nothing. And even that console log is called twice as you can see in console output i dont know why.
But my goal is to print the first name of person into <a>
element and I just don't know how. Hope somebody can help me with this. Thanks for your time.
Think about the state of the app before the fetch occurs - the fetchedData
array is empty. Then when you fetch, you are converting it into an object, with a results
field that is an array.
Your code needs to be able to handle both of these states. Don't try to use or log a field of something that you haven't first verified actually exists, or it will crash.
First step is to clean it up so you directly just update the array in the state -
Your map is not working because fetchedData has an inner results
field - try this.setState({fetchedData: result.results});
, and then console.log(this.state.fetchedData)
.
Also you might want to add some guards to the top of your render
so that things don't crash when the fetchedData is empty or errored:
if (this.state.fetchedData === []) return <p>"Nothing Loaded"</p>;
if (this.state.error !== null) return <p>{this.state.error.message}</p>;
As for the double output to the console, that is because the render
method get run first when the component is mounted, and you see the output where the fetchedData
is empty, and then componentDidMount
runs (which fetches the data and updates the state) and then React re-renders with the new state, causing the second console log.
Your console log that tries to access the .result[0]
fails because it doesn't exist for this first pre-fetch state. Check (with an if) it is there before logging, or log the whole state obj.