Reputation:
I've been using unsplash api to make an image search website. on mounting of the website, the images show fine. But when I enter a search query and click submit then I get data.map is not a function
.
I want to be able to show the search results but I think I'm doing something wrong in the handleSubmit
function where the api call for the search query is done. Help would be appreciated
import React, { Component } from "react";
import Pagination from "./Pagination";
import List from "./List";
import "./styles.css";
import axios from "axios";
const LOAD_STATE = {
SUCCESS: "SUCCESS",
ERROR: "ERROR",
LOADING: "LOADING"
};
const BASE_URL = "https://api.unsplash.com/photos?page=1";
export default class App extends Component {
constructor() {
super();
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.state = {
photos: [],
totalPhotos: 0,
perPage: 5,
currentPage: 1,
loadState: LOAD_STATE.LOADING,
search: ""
};
}
handleChange(e) {
this.setState({ search: e.target.value });
}
handleSubmit() {
const { search, perPage } = this.state;
console.log(search);
const url =
"https://api.unsplash.com/search/photos?page=1&query=" +
search +
"&client_id=" +
appId;
const options = {
params: {
client_id: appId,
page: 1,
per_page: perPage,
order_by: "popularity"
}
};
this.setState({ loadState: LOAD_STATE.LOADING });
axios
.get(url, options)
.then(response => {
this.setState({
photos: response.data,
totalPhotos: parseInt(response.headers["x-total"]),
currentPage: 1,
loadState: LOAD_STATE.SUCCESS
});
})
.catch(() => {
this.setState({ loadState: LOAD_STATE.ERROR });
});
}
componentDidMount() {
this.fetchPhotos(this.state.currentPage);
}
fetchPhotos(page) {
var self = this;
const { perPage } = this.state;
const options = {
params: {
client_id: appId,
page: page,
per_page: perPage,
order_by: "popularity"
}
};
this.setState({ loadState: LOAD_STATE.LOADING });
axios
.get(BASE_URL, options)
.then(response => {
self.setState({
photos: response.data,
totalPhotos: parseInt(response.headers["x-total"]),
currentPage: page,
loadState: LOAD_STATE.SUCCESS
});
})
.catch(() => {
this.setState({ loadState: LOAD_STATE.ERROR });
});
}
render() {
return (
<div className="app">
<input
onChange={this.handleChange}
type="text"
name="search"
placeholder="Enter query"
/>
<button type="submit" onClick={this.handleSubmit} className="button">
Submit
</button>
<Pagination
current={this.state.currentPage}
total={this.state.totalPhotos}
perPage={this.state.perPage}
onPageChanged={this.fetchPhotos.bind(this)}
/>
{this.state.loadState === LOAD_STATE.LOADING ? (
<div className="loader" />
) : (
<List data={this.state.photos} />
)}
</div>
);
}
}
import React from "react";
import ListItem from "./ListItem";
const List = ({ data }) => {
var items = data.map(photo => <ListItem key={photo.id} photo={photo} />); //error in this line
return <div className="grid">{items}</div>;
};
export default List;
Upvotes: 4
Views: 68
Reputation: 65
you should use
axios
.get(url, options)
.then(response => {
const photos = response.data ? response.data.results : [];
this.setState({
photos,
totalPhotos: parseInt(response.headers["x-total"]),
currentPage: 1,
loadState: LOAD_STATE.SUCCESS
});
})
instead of
axios
.get(url, options)
.then(response => {
this.setState({
photos: response.data,
totalPhotos: parseInt(response.headers["x-total"]),
currentPage: 1,
loadState: LOAD_STATE.SUCCESS
});
})
in handleSubmit function
Upvotes: 1