Joe Consterdine
Joe Consterdine

Reputation: 1053

React.js - onChange undefined

I've got the last.fm API working in my app, I'm grabbing related artists. So the idea is you search for an artist and it returns a list of related artists.

If I use 'onClick' it works perfect because it grabs the input value, but I want to use 'onChange' and it seems to returning the wrong results. I think it's because it's undefined at some stages or something!

Any ideas how to fix this?

// AJAX

import axios from "axios";

module.exports = {
  fetchArtistCategory: (artist) => {
    let key = "12345";
    let encodedURI = window.encodeURI('http://ws.audioscrobbler.com/2.0/?method=artist.getsimilar&artist=' + artist + '&api_key=' + key + '&format=json');
    return axios.get(encodedURI)
    .then((res) => {
      return res
    });
  }
}

// App

import React from "react";
import {render} from "react-dom";
import Artists from "./components/Artists.js";
import Api from "./components/Api.js";

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      artist: [],
    }

    this.searchArtist = this.searchArtist.bind(this);
  }
  componentDidMount() {

  }
  searchArtist() {
    Api.fetchArtistCategory(this.searchArtists.value)
    .then((res) => {
      this.setState({
        artist: res.data.similarartists.artist
      });
    })
  }
  render() {
    return (
      <div>
        <Artists artistValue={this.state.artist} />
        <input type="text" placeholder="Search artist" ref={(ref) => this.searchArtists = ref} onChange={this.searchArtist} />
        <input type="submit"/>
      </div>
    )
  }
}

render(<App />, document.getElementById("main"));

Upvotes: 2

Views: 4424

Answers (2)

Aidan Hoolachan
Aidan Hoolachan

Reputation: 2379

It's hard to diagnose your problem without knowing what you mean by "returning the wrong results". My initial guess is that you're thinking about onChange incorrectly.

onchange fires for every single text change. If I typed in "Bob Dylan" into your text field, onChange would fire once for each change as I type (eg. "B", "Bo", "Bob", "Bobe", "Bob"(delete e), "Bob "...). Thus you'll be firing a lot of API requests. This is fine for autocomplete, but requires rate-limiting, smart response ordering, etc., and is a different use case than yours.

It sounds like you only want to fire one API request once the user has completed their thought. To do this, you should try the onfocusout or onblur attributes -- as their names imply, they will fire when the user has completed their input and left the text field.

Upvotes: 2

ceckenrode
ceckenrode

Reputation: 4713

shouldn't you be passing an event through with the onChange handler?

searchArtist(event) {
    Api.fetchArtistCategory(event.target.value)
    .then((res) => {
      this.setState({
        artist: res.data.similarartists.artist
      });
    })
  }

^ The only piece of code you should need to change if everything else if correct

And you need the ref unless I'm misunderstanding. You get the value of the input field as event.target.value inside of the event handler.

Upvotes: -1

Related Questions