1

I've gone through the react docs and tried to implement the all of the conditional example but it doesn't seem to be working on my code. Here is my code:

class Main extends React.Component {
 constructor(props) {
   super(props);
   this.onChange = this.onChange.bind(this);
   this.handleSubmit = this.handleSubmit.bind(this);
   this.state = {items: [],text: ''};
}
onChange(e) {
   this.setState({text: e.target.value});
}
handleSubmit(e) {
   e.preventDefault();
   let newItem = this.state.items;
   let text = this.state.text;
   newItem.push(text);
   let newText = '';
   this.setState({items: newItem, text: newText});
}
 render() {
  return (
    <div className="container">
     <div className="inside-box">
      <h4>Javascript Library</h4>
     </div>
     <form onSubmit={this.handleSubmit}>
       <input
         type="text"
         onChange={this.onChange}
         value={this.state.text}
         placeholder="Add your item..." />
      </form>
      {/* this will compare the input that I submitted and compare with the library. It will show result if the is a library or else it will show an error */}
      {library === this.state.items && <Result /> }
     </div>
   )
  }
}


const Result = ()  => {
    return <h1>There is a library</h1>; 
}

const Error = ()  => {
    return <h1>There is no such library</h1>; 
}


var library = ['react', 'angular', 'vue'];

ReactDOM.render(<Main />, document.getElementById('app'));

I'me kinda stuck right now. I tried to use if else and ternary operator and still doesn't work. I wanted to parse the input to the library data. Here is the codepen. Any help would be appreciated

Irsyad14
  • 74
  • 2
  • 10

2 Answers2

1

The problem here is you are trying to compare two arrays using the equals operator which will always be false. Array comparisons are based off reference not value so since these two arrays don't share the same reference in memory they are not equal.

libraries such as Lodash provide _.isEqual which allows you to compare two arrays together otherwise you'd want to look into functions that allow you to compare two arrays.

In console if you do [] === [] it will return false as an example.

also see How to compare arrays in JavaScript?

a helper method to solve would be :

function arrayComparator(arr1, arr2) {
  arr1 = arr1.sort();
  arr2 = arr2.sort();
  return arr1.length === arr2.length && arr1.every(function(item, index) {
    return item === arr2[index];
  })
}

then can just do {arrayComparator(library, this.state.items) && <Result />}

this helper method will stop working once you have an array of objects and you would have to program around that as well but if its just comparing two arrays with string and numbers it will work fine.

here is a working pen http://codepen.io/finalfreq/pen/GrQdEK?editors=1010

Community
  • 1
  • 1
finalfreq
  • 6,830
  • 2
  • 27
  • 28
  • Thanks for the help. Now everything is clear to me. Just one thing. I actually wanted it to be like, when i submitted 'react', it will show the result 'there is a library'. From your solution, I need to actually submitted 'react', 'angular', 'vue' and then the result will show. – Irsyad14 Jan 31 '17 at 22:48
  • in that case you can just do function arrayIncludes(arr1, arr2) { return arr1.some(function(item){ return arr2.includes(item) }) } and then do `{arrayIncludes(library, this.state.items) && }` edited my codepin with that change – finalfreq Jan 31 '17 at 22:54
  • I've tried around your code. So if I wanted to do the error if submitted a wrong one, how about should i do this? ` {arrayIncludes(library, this.state.items) ? : }` if I did it like this, it will only work partially. It will either show first or first depending whether which one is submitted first. But it doesn't change for the subsequent submission. – Irsyad14 Jan 31 '17 at 23:23
  • Below the conditional that exists just add: `{!arrayIncludes(library, this.state.items) && this.state.items.length > 0 && }` – finalfreq Jan 31 '17 at 23:30
1

It is not completely clear to me what you want to do in your code but if you want to check if what you write in the input is a library or not you probably want something like: {library.indexOf(this.state.text)!=-1?<Result /> :<Error/>}

edit:

I think what you want is to check every item in the state individually if there is a library or not. thus i recommend you to something like this :

{this.state.items.map((item)=><div>{item} {library.indexOf(item)!=-1?<Result /> :<Error/>}</div>)}

codepen

JJJ
  • 337
  • 3
  • 7
  • I was trying to compare between library array and 'this.state.items' array. So that when I hit enter on the input field, the will show. But from what @finalfreq has explained, I can't compare between two arrays. – Irsyad14 Jan 31 '17 at 22:40
  • @Irsyad14 i have updated my answer with a workaround for your use case but it wont work in all cases and highly suggest checking out lodash which will work for almost all use cases when to comes to their helper methods. – finalfreq Jan 31 '17 at 22:43
  • Just to be clearer, for example if i typed in 'react', the result will show 'there is a library'. – Irsyad14 Jan 31 '17 at 22:46
  • @Irsyad14 I edit my answer to support individual check of the items you add. so that if you type react it will show there is a library for react. but if you add test'. it will only say there is a library for react not 'test' – JJJ Jan 31 '17 at 22:56