Reputation:
I've tried to create an image search application using unsplash api but it shows the error TypeError: data.map is not a function
. It was working fine till last night but now it suddenly shows this error. It initially loaded the page with the images but it started showing this error when I searched for moon and went to last page. I then refreshed the page and it displays the images again but as soon as I did per_page items from 5 to 9 then it shows the error again and now it''s continously showing the error. Is it a problem with the api? but even if it was the api, it should show a blank page because I did photos: []
in the try catch block in the api call method but instead it shows the error. I'm not sure what is wrong with my code. Can someone help me please
App.js
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 appId = "N1ZIgf1m1v9gZJhledpAOTXqS8HqL2DuiEyXZI9Uhsk";
export default class App extends Component {
constructor() {
super();
this.handleChange = this.handleChange.bind(this);
this.fetchPhotos = this.fetchPhotos.bind(this);
this.state = {
photos: [],
totalPhotos: 0,
perPage: 5,
currentPage: 1,
loadState: LOAD_STATE.LOADING,
search: ""
};
}
handleChange(e) {
this.setState({ search: e.target.value });
}
componentDidMount() {
this.fetchPhotos(this.state.currentPage);
}
fetchPhotos(page = 1) {
var self = this;
const { search, perPage } = this.state;
const url1 = `https://api.unsplash.com/photos?page=${page}&client_id=${appId}`;
const url2 =
`https://api.unsplash.com/search/photos?page=${page}&query=` +
search +
"&client_id=" +
appId;
const url = search ? url2 : url1;
if (search) {
const options = {
params: {
page: page,
per_page: perPage,
order_by: "popularity"
}
};
this.setState({ loadState: LOAD_STATE.LOADING });
axios
.get(url, options)
.then(response => {
console.log(typeof response.data);
let photos;
try {
photos = response.data.results;
} catch {
photos = [];
}
this.setState({
photos,
totalPhotos: parseInt(response.headers["x-total"]),
currentPage: page,
loadState: LOAD_STATE.SUCCESS
});
})
.catch(() => {
this.setState({ loadState: LOAD_STATE.ERROR });
});
} else {
const options = {
params: {
client_id: appId,
page: page,
per_page: perPage,
order_by: "popularity"
}
};
this.setState({ loadState: LOAD_STATE.LOADING });
axios
.get(url, options)
.then(response => {
console.log(typeof response.data);
let photos;
try {
photos = response.data;
} catch {
photos = [];
}
self.setState({
photos,
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.fetchPhotos(1)}
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} />
)}
<Pagination
current={this.state.currentPage}
total={this.state.totalPhotos}
perPage={this.state.perPage}
onPageChanged={this.fetchPhotos.bind(this)}
/>
</div>
);
}
}
List.js
import React from "react";
import ListItem from "./ListItem";
const List = ({ data }) => {
var items = data.map(photo => <ListItem key={photo.id} photo={photo} />); //error here
return <div className="grid">{items}</div>;
};
export default List;
Upvotes: 0
Views: 133
Reputation: 337
I found out the problem that you are facing, the issue is when there is empty data from the API response the photos variable stays like photos = {}
where in expected is photos = []
, which you did in catch
block but it never goes to catch block because having empty data is not error, also I have solved your issue here Demo.
Upvotes: 1