react-interview-code/src/APIRequest.js

78 lines
2.2 KiB
JavaScript

import React from 'react';
import './APIRequest.css';
export default class APIRequest extends React.Component {
constructor(props) {
super(props);
this.state = {
img: "",
maxNum: 0,
num: "",
alt: "",
title: "Loading Comic..."
};
}
componentDidMount() {
this.fetchComic().catch(e => {
console.error("Failed to fetch initial comic! : ", e);
});
}
updateComicFromAPI(data) {
this.setState(old => {
if(old.num !== "" && old.num !== data.num) return {};
return {
img: data.imgRetina ? data.imgRetina : data.img,
maxNum: data.num > old.maxNum ? data.num : old.maxNum,
num: data.num,
alt: data.alt,
title: data.title
};
});
}
fetchComic() {
return fetch(`https://xkcd.now.sh/${this.state.num}`).then(
response => response.json()
).then(x => this.updateComicFromAPI(x));
}
fetchNext() {
this.setState(old => ({num: ++old.num}), () => {
this.fetchComic().catch( err => {
console.error("Error fetching next comic: ", err);
});
});
}
fetchPrevious() {
this.setState(old => ({num: --old.num}), () => {
this.fetchComic().catch( err => {
console.error("Error fetching prev comic: ", err);
});
});
}
render() {
const s = this.state;
const prev = s.num > 0 ?
<button className="btn" onClick={() => this.fetchPrevious()}>Previous</button> :
"";
const next = s.num < s.maxNum ?
<button className="btn" onClick={() => this.fetchNext()}>Next</button> :
"";
return <section className="card mt-3 comic-component" >
<div className="card-body">
<p>This interviewer requested I write a component that makes an API
call and displays it. I did a bit more than that since it was more
fun and I think better deomnstrated my ability to make API calls.</p>
<div className="comic-nav">{prev}{next}</div>
<h5 className="card-title">{s.title}</h5>
{ s.img ? <img className="comic-image" src={s.img} title={s.alt} /> : "" }
<p>All comics from <a href="https://Xkcd.com">xkcd web comic</a></p>
</div>
</section>;
}
}