4

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;

2
  • Would be helpful and faster to have Plunker with your sample. Commented Mar 28, 2018 at 17:33
  • Try responseData.data.results in setState. Commented Mar 28, 2018 at 17:39

1 Answer 1

1
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.

Sign up to request clarification or add additional context in comments.

1 Comment

thank you so much for your help! That fixed the problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.