2
votes

I am new to React and javascript and trying to use moroshko's component react-autosuggest, but failing to get event handlers to bind correctly. I'm writing in coffeescript, but will paste compiled javascript too.

define [
  'jquery',
  'react',
  'reactdom',
  'autosuggest'
], (jQuery, React, ReactDOM, Autosuggest) ->
  escapeRegexCharacters = (str) ->
    str.replace /[.*+?^${}()|[\]\\]/g, '\\$&'
  getSuggestions = (praxes, value) ->
    if value == ""
      return []
    val = escapeRegexCharacters(value.trim())
    regex = new RegExp('^' + val, 'i')
    praxes.filter((prax) => regex.test(prax.species))
  getPraxSpecies = (prax) ->
    prax.species
  renderSpecies = (prax) ->
    React.createElement("span", null, getPraxSpecies(prax))

  Species = React.createClass
    getInitialState: ->
      value: ''
      suggestions: getSuggestions(@props.praxes, '')

    onChange: (event, {newValue}) ->
      @setState({value: newValue})

    onSuggestionsUpdateRequested:  ({value}) ->
      @setState {suggestions: getSuggestions(@props.praxes, value)}

    render: ->
      inputProps =
        placeholder: "Choose a species"
        value: ''
        onChange: @onChange
      autosuggest = React.createFactory Autosuggest
      React.DOM.div {key: 'autosugg', className: 'praxis'},
        autosuggest {
          key: 'autoSp',
          suggestions: @state.suggestions,
          onSuggestionsUpdateRequested: @onSuggestionsUpdateRequested,
          getSuggestionValue: getPraxSpecies,
          renderSuggestion: renderSpecies,
          inputProps: inputProps
        }
    Species

or coffeescript above compiled to javascript below:

(function() {
  define(['jquery', 'react', 'reactdom', 'autosuggest'], function(jQuery, React, ReactDOM, Autosuggest) {
    var Species, escapeRegexCharacters, getPraxSpecies, getSuggestions, renderSpecies;
    escapeRegexCharacters = function(str) {
      return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    };
    getSuggestions = function(praxes, value) {
      var regex, val;
      if (value === "") {
        return [];
      }
      val = escapeRegexCharacters(value.trim());
      regex = new RegExp('^' + val, 'i');
      return praxes.filter((function(_this) {
        return function(prax) {
          return regex.test(prax.species);
        };
      })(this));
    };
    getPraxSpecies = function(prax) {
      return prax.species;
    };
    renderSpecies = function(prax) {
      return React.createElement("span", null, getPraxSpecies(prax));
    };
    return Species = React.createClass({
      getInitialState: function() {
        return {
          value: '',
          suggestions: getSuggestions(this.props.praxes, '')
        };
      },
  onChange: function(event, _arg) {
    var newValue;
    newValue = _arg.newValue;
    return this.setState({
      value: newValue
    });
  },
      onSuggestionsUpdateRequested: function(_arg) {
        var value;
        value = _arg.value;
        return this.setState({
          suggestions: getSuggestions(this.props.praxes, value)
        });
      },
      render: function() {
        var autosuggest, inputProps;
        inputProps = {
          placeholder: "Choose a species",
          value: '',
          onChange: this.onChange
        };
        autosuggest = React.createFactory(Autosuggest);
        console.log('this: ' + this);
        return React.DOM.div({
          key: 'autosugg',
          className: 'praxis'
        }, autosuggest({
          key: 'autoSp',
          suggestions: this.state.suggestions,
          onSuggestionsUpdateRequested: this.onSuggestionsUpdateRequested,
          getSuggestionValue: getPraxSpecies,
          renderSuggestion: renderSpecies,
          inputProps: inputProps
        }));
      }
    }, Species);
  });

}).call(this);

The autosuggest component displays properly initially, accepts input, and calls onChange and onSuggestionsUpdateRequested functions in that order. State is updated, but possibly not attached to the correct component. The autosuggest then repaints exactly as initially (i.e. value='').

Substituting fat-arrow => for -> in defining onChange results in an error: Uncaught TypeError: _this.setState is not a function

I have also tried using the coding style of moroshko's example without success. Clearly, I am missing something ...

1
I don't see any JavaScript. It looks like you pasted the coffeescript in both locations. - Brandon
Thanks. Yes. Replaced 2nd cs w/ js. - jehrlich
yeah but I'm not sure the js you posted matches the CoffeeScript. The JS for onChange looks like you used the fat arrow? You definitely do not want that - Brandon
another mistake, now fixed. -> onChange is onChange: function(event, _arg) { var newValue; newValue = _arg.newValue; return this.setState({ value: newValue }); }, - jehrlich

1 Answers

2
votes

I think the problem is in your inputProps. You need to use this.state.value:

 inputProps =
    placeholder: "Choose a species"
    value: ''
    onChange: @onChange

to:

 inputProps =
    placeholder: "Choose a species"
    value: @state.value
    onChange: @onChange