user14008727
user14008727

Reputation:

search data not displayed

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

Answers (1)

sarpere
sarpere

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

Related Questions