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

1
  • You aren't calling the Error component anywhere. It will render Result if library === items or else does nothing. Commented Jan 31, 2017 at 22:27

2 Answers 2

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

Sign up to request clarification or add additional context in comments.

4 Comments

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.
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) && <Result /> } edited my codepin with that change
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) ? <Result /> : <Error />}` if I did it like this, it will only work partially. It will either show <Result /> first or <Error /> first depending whether which one is submitted first. But it doesn't change for the subsequent submission.
Below the conditional that exists just add: {!arrayIncludes(library, this.state.items) && this.state.items.length > 0 && <Error /> }
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

4 Comments

I was trying to compare between library array and 'this.state.items' array. So that when I hit enter on the input field, the <Result /> will show. But from what @finalfreq has explained, I can't compare between two arrays.
@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.
Just to be clearer, for example if i typed in 'react', the result will show 'there is a library'.
@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'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.