JavaScript

Lance Chandler
PRO
Lance Chandler
Front End Web Development Techdegree Graduate 17,222 Points

Project 11 - Search Component - TypeError:_this.performSearch is not a function

I am trying to call the function: performSearch or even better the component: FetchContainer when text is typed into the "Search" field on the form:

TypeError: _this.performSearch is not a function Search._this.handleSubmit src/components/Search.js:25 22 | // Input field's value 23 | let checkquery = (this.query.value); 24 | console.log('You typed "'+ checkquery + '" in the Search field');

25 | this.performSearch(this.query.value); 26 | e.currentTarget.reset(); 27 | } 28 |

Search.js: // Search input Text & Maginfying Glass button import React, { Component } from 'react';

//import Apps import FetchContainer from './FetchContainer';

export default class Search extends Component { // State specific for this component that is updated // by onSearchChange function that users type Text // into input field of the Form state = { searchText: '' }

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

// Function that is called when the Form is submitted handleSubmit = e => { e.preventDefault(); // Input field's value let checkquery = (this.query.value); console.log('You typed "'+ checkquery + '" in the Search field'); this.performSearch(this.query.value); e.currentTarget.reset(); }

render() { return ( <div> <form className="search-form" onSubmit={this.handleSubmit} > <input type="search" onChange={this.onSearchChange} name="search" ref={(input) => this.query = input} // Puts a reference to the input on the Search form class placeholder="Search" /> <button type="submit" className="search-button"> <svg fill="#fff" height="24" viewBox="0 0 23 23" width="24" xmlns="http://www.w3.org/2000/svg"> <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/> <path d="M0 0h24v24H0z" fill="none"/> </svg> </button> </form> </div> ); } }

FetchContainer.js: // Container component that takes in a keyword and api key as props // and fetches the photos and other required information from the API import React, { Component } from 'react';

// a promised-based library that makes server requests in React // It will ne used to fetch the data from Flickr import axios from 'axios';

// import api_key assigned from Flickr Website located in Config.js // to be used with the Axios 'get' statement import apiKey from './Config' ;

// App components import PhotoContainer from './PhotoContainer';

export default class FetchContainer extends Component { // Initialize State for data that is going to change constructor() { super(); this.state = { // State is the 'photos' data we want to display photos: [], loading: true, query: '' }; }

// componentDidMount is used to "fetch data from a server" with AJAX calls (axios will perform) componentDidMount() { // axios (get method) - uses Javascript Promises to handle results. Promises let you chain methods (callbacks) in a sequential order // URL is a Template Literal so we can embed the values of: apikey & query axios.get(https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=${apiKey}&text=${this.props.query}&per_page=16&format=json&nojsoncallback=1) // Response object executed once results are obtained from Flickr .then(response => { this.setState({ photos: response.data.photos.photo, loading: false, query: '' }); }) // catch method - handles any errors fetching data .catch(error => { console.log('Error fetching and parsing data', error); }); }

performSearch = (query) => { axios.get(https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=${apiKey}&text=${this.props.query}&per_page=16&format=json&nojsoncallback=1) // Response object executed once results are obtained from Flickr .then(response => { this.setState({ photos: response.data.photos.photo, loading: false }); }) // catch method - handles any errors fetching data .catch(error => { console.log('Error fetching and parsing data', error); }); }

render() { console.log(this.state.photos); return ( <div className="photo-container"> { (this.state.loading) ? <p>Loading...</p> : <PhotoContainer data={this.state.photos} /> } </div> ); } }

Totally stumped on how to proceed. Been trying for days. Any guidance would be greatly appreciated.

2 Answers

Steven Parker
Steven Parker
130,505 Points

Your "handleSubmit" callback is implemented as an arrow function, and one of the differences between those and conventional functions is that they do not establish a value for "this".

But since you have the passed-in event object as "e", you can substitute "e.target" instead.