98

I have a map()function that needs to display views based on a condition. I've looked at the React documentation on how to write conditions and this is how you can write a condition:

{if (loggedIn) ? (
  // Hello!
) : (
  // ByeBye!
)}

Here's the link: https://facebook.github.io/react/docs/conditional-rendering.html#inline-if-else-with-conditional-operator

So, I tried to take that knowledge and implemant it in my React app. And it turned out like this:

render() {
  return (
    <div>
      <div className="box">
        {this.props.collection.ids
          .filter(
            id =>
              // note: this is only passed when in top level of document
              this.props.collection.documents[id][
                this.props.schema.foreignKey
              ] === this.props.parentDocumentId
          )
          .map(id =>
            {if (this.props.schema.collectionName.length < 0 ? (

              <Expandable>
                <ObjectDisplay
                  key={id}
                  parentDocumentId={id}
                  schema={schema[this.props.schema.collectionName]}
                  value={this.props.collection.documents[id]}
                />
              </Expandable>

            ) : (
              <h1>hejsan</h1>
            )}
          )}
      </div>
    </div>
  )
}

But it doesn't work..! Here's the error:

Screenshot

I appreciate all the help I can get!

1
  • 3
    The error is a syntax one and is based on the fact that you are trying to use a ternary operator and an if statement incorrectly. Commented Jul 7, 2017 at 11:44

8 Answers 8

161

You are using both ternary operator and if condition, use any one.

By ternary operator:

.map(id => {
    return this.props.schema.collectionName.length < 0 ?
        <Expandable>
            <ObjectDisplay
                key={id}
                parentDocumentId={id}
                schema={schema[this.props.schema.collectionName]}
                value={this.props.collection.documents[id]}
            />
        </Expandable>
    :
        <h1>hejsan</h1>
}

By if condition:

.map(id => {
    if(this.props.schema.collectionName.length < 0)
        return <Expandable>
                  <ObjectDisplay
                      key={id}
                      parentDocumentId={id}
                      schema={schema[this.props.schema.collectionName]}
                      value={this.props.collection.documents[id]}
                  />
              </Expandable>
    return <h1>hejsan</h1>
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks man! I did notice that I used both :// Which one is preferred?
It is case by case but the fundamental difference is that if-else clause is a construct, ternary is an expression. And in JSX, only an expression can be placed directly under the JS block {}.
i think primarily opinion based, but what i prefer is: if you want to check only one condition then use ternary operator otherwise use if/else ladder for multiple conditions :)
Alright! But how does it now what's true and what's isn't? When using if condition I'm not using any ? nor :.
@MartinNordström sorry didn't get the last one, can you explain more?
39

If you're a minimalist like me. Say you only want to render a record with a list containing entries.

<div>
  {data.map((record) => (
    record.list.length > 0
      ? (<YourRenderComponent record={record} key={record.id} />)
      : null
  ))}
</div>

2 Comments

Did you solve the error you encountered @johnk?
yup, it was bad data
13

There are two syntax errors in your ternary conditional:

  1. remove the keyword if. Check the correct syntax here.
  2. You are missing a parenthesis in your code. If you format it like this:

    {(this.props.schema.collectionName.length < 0 ? 
       (<Expandable></Expandable>) 
       : (<h1>hejsan</h1>) 
    )}
    

Hope this works!

Comments

8

This one I found simple solutions:

row = myArray.map((cell, i) => {

    if (i == myArray.length - 1) {
      return <div> Test Data 1</div>;
    }
    return <div> Test Data 2</div>;
  });

Comments

6

Remove the if keyword. It should just be predicate ? true_result : false_result.

Also ? : is called ternary operator.

2 Comments

One can have if inside a function. Even if a ternary also works, you shouldn't suggest to remove something that's technically perfectly valid.
@Chris: that's a fair comment but the OP's error is based on a syntax error created by trying to combine both an if statement and the ternary operator incorrectly...
3

You're mixing if statement with a ternary expression, that's why you're having a syntax error. It might be easier for you to understand what's going on if you extract mapping function outside of your render method:

renderItem = (id) => {
    // just standard if statement
    if (this.props.schema.collectionName.length < 0) {
        return (
            <Expandable>
                <ObjectDisplay
                    key={id}
                    parentDocumentId={id}
                    schema={schema[this.props.schema.collectionName]}
                    value={this.props.collection.documents[id]}
                />
            </Expandable>
        );
    }
    return (
        <h1>hejsan</h1>
    );
}

Then just call it when mapping:

render() {
    return (
        <div>
            <div className="box">
                { 
                    this.props.collection.ids
                        .filter(
                            id =>
                            // note: this is only passed when in top level of document
                            this.props.collection.documents[id][
                                this.props.schema.foreignKey
                            ] === this.props.parentDocumentId
                        )
                        .map(this.renderItem)
                }
            </div>
        </div>
    )
}

Of course, you could have used the ternary expression as well, it's a matter of preference. What you use, however, affects the readability, so make sure to check different ways and tips to properly do conditional rendering in react and react native.

Comments

2

Just in case:

If only: (Use && without ? : or else)

When you don't have to return anything when else

Examples: (Array or Object)

// const someArray = ['a', 'b', 'c']
{someArray.map(
  (v) =>
    someCondition && (
      <></> // {v}
    )
)}

// const someObject = {a: '1', b: '2', c: '3'}
{Object.keys(someObject).map(
  (k) =>
    someCondition && (
      <></> // {someObject[k]} (Remember: add key={k} in wrapper)
    )
)}

Comments

-1

That the ternary operator works but not if-else statements is rather ridiculous and makes complex logic a pain. The former seems to be the only solution though.

Comments

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.