4

I have array of cities with objects like this:

[{id: 1, name: 'New York'}, {id: 2, name: 'London'} ...]

and I have a value of id.

I put elements (names) from array to select list. But I need to add first option with value from array (name) which have the corresponding id which I can't make it work.

My component:

const propTypes = {  
  cities: PropTypes.array,  
  enteredEvent: PropTypes.array  
};

class newEvent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      showInOption: ''
    };
    this.handleDictionary = this.handleDictionary.bind(this);
    this.searchTypeEvent = this.searchTypeEvent.bind(this);
  }

  componentDidMount() {
    this.searchTypeEvent();
  }

  handleDictionary(e) {
    ...
  }

  searchTypeEvent() {
    if (this.props.enteredEvent.cityid !== null && this.props.enteredEvent.cityid !== undefined) { // if I have id value
      const type = this.props.cities.find(el => el.id === this.props.enteredEvent.cityid); // find an object with id
      this.setState({ showInOption: type.name });
    }
    this.setState({ showInOption: 'Select something' });
  }

  render() {
    return (
      <div>       
        <select onChange={this.handleDictionary}>
          <option>{this.state.showInOption}</option> // here I need to add a value
          {this.props.cities.map(item => {   // here I call other options
            return (<InputSelect key={item.id} directory={item}/>);
          })}
        </select>        
      </div>
    );
  }
}

I have an error:

Uncaught TypeError: Cannot read property 'name' of undefined

How can I fix it?

Hemadri Dasari
  • 32,666
  • 37
  • 119
  • 162
Jack
  • 514
  • 3
  • 11
  • 30
  • You try to find an item by a search term by looking at the ids, is that intended? `el.id === this.props.enteredEvent.cityname`. You must also make sure that you actually find a `type` before trying to access `name` on it. – Tholle Nov 13 '18 at 14:38
  • It's unknown what `cityname`. If it derives from an input, it's unlikely that it is a number that can pass `===` check. – Estus Flask Nov 13 '18 at 14:39
  • @Tholle this.props.enteredEvent.cityid is correct. My mistake in post. I get object which I need (after find), but I can't get name value – Jack Nov 13 '18 at 14:51
  • @estus this.props.enteredEvent.cityid is correct. My mistake in post – Jack Nov 13 '18 at 14:51
  • Write `console.log(type);` right after the `find` and you will get `undefined` as the error says. I think it's a good idea to guard against the case when the `cityid` doesn't match a `cities` object id. – Tholle Nov 13 '18 at 14:55
  • @Jack Then `cityid` it is. If it's not a number then it won't work. It's unknown where it comes from, so it's impossible to say what exactly goes wrong. Please, provide https://stackoverflow.com/help/mcve that allows other users to replicate the problem. – Estus Flask Nov 13 '18 at 14:57
  • @Tholle When I call this function from option and in function I return value, this function called 6 times, and in last call I get the object value (I catch it, using console.log). Maybe React doesn't have time to perform this function? – Jack Nov 13 '18 at 15:02
  • @estus When I call this function from option and in function I return value, this function called 6 times, and in last call I get the object value (I catch it, using console.log). Maybe React doesn't have time to perform this function? – Jack Nov 13 '18 at 15:02
  • It possibly is. This is a complex issue parts of which aren't shown, so there should be a way for other users to debug it - Stackblitz, etc. Please, provide it if you're interested in answer that works because current answers are guesswork. – Estus Flask Nov 13 '18 at 15:30
  • Probably `this.props.enteredEvent` is not set, you should console.log it in `searchTypeEvent` and maybe set a default value when it's missing. – HMR Nov 13 '18 at 15:30

2 Answers2

6

It seems you need filter.It will return an array of object

let a = [{
  id: 1,
  name: 'New York'
}, {
  id: 2,
  name: 'London'
}]

function b(idToSearch) {
  return a.filter(item => {
    return item.id === idToSearch
  })
};

console.log(b(1))
brk
  • 48,835
  • 10
  • 56
  • 78
4

Try this

  const type = Array.isArray(this.props.cities) && this.props.cities.find(el => el.id ==this.props.enteredEvent.cityid);
  this.setState({ showInOption: type ? type.name : null });

Make sure the name you enter matches with any one of the object in array

Hemadri Dasari
  • 32,666
  • 37
  • 119
  • 162
  • When I call this function from option and in function I return value, this function called 6 times, and in last call I get the object value (I catch it, using console.log). Maybe React doesn't have time to perform this function? – Jack Nov 13 '18 at 15:00
  • no, it isn't help for my. I think there is asynchronous React problem – Jack Nov 13 '18 at 15:23
  • 1
    Worked perfect for me ! thanks very much! Exactly what I wanted !! :) – Andrew Irwin Jan 31 '19 at 15:30