Biii
Biii

Reputation: 3431

Search functionality and fetch api in React

I'm working on an app that makes a call to Unsplash's API and displays the response. I was able to get/display the response easily with just the /photos endpoint when I had the fetch request in the componentDidMount(), but I want to make the app searchable, so I added performSearch() with a default query.

But adding performSearch caused this error: TypeError: cannot read property 'map' of undefined

This is the JSON I'm getting back when I test: Search endpoint + query

I've tried other solutions I've found on the forums, but so far nothing's fixed the problem. I'm definitely getting back an array, so shouldn't map work?

class App extends Component {

  constructor() {
    super();
    this.state = {
      results: [],
      loading: true
    };
  }

  componentDidMount() {
    this.performSearch();
  }

  performSearch = (query = 'camping') => {
    fetch(`https://api.unsplash.com/search/photos?page=3&query=${query}&client_id=${client_id}`)
      .then(response => response.json())
      .then(responseData => {
        this.setState({
          results: responseData.data,
          loading: false
        });
      })
      .catch(error => {
        console.log('Error fetching and parsing data', error);
      });
  }

  render() {

    return ( 
      <div className = "App">
        <SearchPhotos onSearch = {this.performSearch} /> 
        <div> 
          {
            (this.state.loading) ? <p>Loading</p> :<PhotoList results={this.state.results} />
          } 
        </div> 
      </div>
    );
  }
}

export default App;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

import React from 'react';

const PhotoList = props =>

    <ul>
        {props.results.map((result, index) =>
            <li key={index}>
                <img src={result.urls.small} key={result.id} />
            </li>
        )}
    </ul>;

export default PhotoList;

import React, { Component } from 'react';


class SearchPhotos extends Component {

    state = {
        searchText: ''
    }

    onSearchChange = e => {
        this.setState({
            searchText: e.target.value
        });
    }

    handleSubmit = e => {
        e.preventDefault();
        this.props.onSearch(this.query.value);
        e.currentTarget.reset();
    }

    render() {
        return(
            <form className="search-form" onSubmit={this.handleSubmit}>
                <input type="search"
                    onChange={this.onSearchChange}
                    name="search"
                    ref={(input) => this.query = input}
                    placeholder="Search..." />
                <button className="search-button" type="submit" id="submit">Go!</button>
            </form>
        );
    }
}

export default SearchPhotos;

Upvotes: 4

Views: 15625

Answers (1)

Subin Sebastian
Subin Sebastian

Reputation: 10997

performSearch = (query = 'camping') => {
    fetch(`https://api.unsplash.com/search/photos?page=3&query=${query}&client_id=${client_id}`)
      .then(response => response.json())
      .then(responseData => {
        this.setState({
          results: responseData.results,
          loading: false
        });
      })
      .catch(error => {
        console.log('Error fetching and parsing data', error);
      });
  }

responseData.results is the array that your are looking for.

Upvotes: 1

Related Questions