Bruno Pigatto
Bruno Pigatto

Reputation: 67

Only one function getting result

I have this two funcions being called, but only the second one is showed on the table.

<table className="tableList tableList--space">
     <thead>{this.tableHead()}</thead>
     <tbody>
          {this.state.products.map((item) =>
               this.tableBody(item) && this.tableBodyComplements(item)
          )}
     </tbody>
</table>

Functions:

tableBody = (item) => (
    <tr key={item.title}>
        <td className="text-left">
            {item.title}
        </td>
        <td className="text-left"> - </td>
        <td className="text-right">R$ {item.price}</td>
        <td className="text-center">{item.quantity}X</td>
        <td className="text-right">R$ {item.total}</td>
        <td className="text-left"></td>
    </tr>
);

tableBodyComplements = (item) => (
    <tr>
        <td className="text-right"> 
            {item.ComplementCategories.map(aux => {
                return aux.Complements[0].title
            })} 
        </td>
        <td className="text-right"> - </td>
        <td className="text-right"> - </td>
        <td className="text-right"> 
            {item.ComplementCategories.map(aux => {
                return aux.Complements[0].quantity
            })} 
        </td>
        <td className="text-right">R$ {item.total}</td>
        <td className="text-right"></td>
    </tr>
);

Why is it only the second one is getting the desire result? I dont know if only the second one is being called or it is overlapping the first one in the table, How can I understand this better and fix it?

Upvotes: 0

Views: 51

Answers (3)

sid c
sid c

Reputation: 195

The && operator actually doesn't return both. It returns the second argument if the first argument is true, otherwise it returns false. For example:

function Example() {
   return (
      <div>
         {"Word1" && "Word2"}
      </div>
   ) // this displays ONLY "Word2", since "Word1" is not a false value.
}

To fix this, wrap them in a fragment:

 {this.state.products.map((item) => 
     <React.Fragment>
        {this.tableBody(item)}
        {this.tableBodyComplements(item)}
     </React.Fragment>
 )}

Upvotes: 1

Robin Zigmond
Robin Zigmond

Reputation: 18249

In javascript, any expression of the form

a && b

or

a || b

will only evaluate to either a or b. Never both. In fact it's not even clear what evaluating to "both a and b" would even mean in general.

In your case, you want to render both elements as JSX - so simply put them after each other, wrapping in a Fragment so that it's a legal React element:

{this.state.products.map((item) =>
    <React.Fragment>
         {this.tableBody(item)}
         {this.tableBodyComplements(item)}
    </React.Fragment
)}

Upvotes: 1

Cory Harper
Cory Harper

Reputation: 1055

Your current implementation is performing what's called a "short-circuit", basically as long as the first value evaluates to a truthy value, the second will be returned, else it probably returns undefined.

To fix your implementation this is what it should look like:

<table className="tableList tableList--space">
     <thead>{this.tableHead()}</thead>
     <tbody>
          {this.state.products.map((item) => (
               <React.Fragment>
                 {this.tableBody(item)}
                 {this.tableBodyComplements(item)}
               </React.Fragment>
            )
          )}
     </tbody>
</table>

Upvotes: 1

Related Questions