How can call multiple function in React ternary if else condition - reactjs

I can not call multiple functions in react js if else ternary condition.
const preATCHandler = ( id, itemNumber ) => {
itemNumber > 0
? (setAtcBtn(false), setQty(itemNumber), dispatch(addToCart(id, Number(itemNumber))))
: (dispatch(removeFromCart(id)), setAtcBtn(true))
}

I can not call multiple functions in ternary operator because it is inline condition.
Finaly take help from wxker.
I use this.
const preATCHandler = ( id, itemNumber ) => {
if (itemNumber){
setAtcBtn(false);
dispatch(addToCart(id, Number(itemNumber)));
}else {
dispatch(removeFromCart(id));
setAtcBtn(true);
}
}

Related

How to access values by key from modified React final form

I was making confirmation when the user tried to close the form by modified and values length > 0.
if (modified) {
return (
Object.keys(modified).filter(
(modifiedItem) => modified[modifiedItem] && values[modifiedItem]?.length > 0,
).length > 0
)
}
Everything is working fine until there are values with an array:
when I try to access by values[answers.0.icon] there is undefined, of course, it should be accessed by values.answers[0].icon, by is it possible to do it when iterating modified keys? Or another way should be appreciated.
Thank you beforehand.
Below screenshots of values:
Modified keys:
I'd suggest to include lodash and use the get function. This will resolve the "path" for you.
For example _.get(values, modifiedItem).
More info can be found at https://lodash.com/docs/4.17.15#get
you could add undefined and null in the if statement, to check if it's true and not undefined and not null before it filter else it will be null or you can put something else.
if (modified && modified !== undefined && modified !== null) {
return (
Object.keys(modified).filter(
(modifiedItem) => modified[modifiedItem] && values[modifiedItem]?.length > 0,
).length > 0
)
}
else {
null
}
You can perhaps check for such situation if its an array and treat it differently.
I agree with solution provided by #Stijn answer, however if you dont wanna carry unnecessary baggage of Lodash you can use below code.
const parseDeep = (obj, path, def) => (() => typeof path === 'string' ?
path.replace(/\[(\d+)]/g,'.$1') : path.join('.'))()
.split('.')
.filter(Boolean)
.every(step => ((obj = obj[step]) !== undefined)) ? obj : def
if (modified) {
return (
Object.keys(modified).filter(
(modifiedItem) =>
Array.isArray(modifiedItem) ?
modified[modifiedItem] && parseDeep(values, modifiedItem, false) : //modify as required
modified[modifiedItem] && values[modifiedItem]?.length > 0,
).length > 0
)
}

ReactJS : Using function as props to return value for <td> gives <Component/> error

I have the following function:
budgetList() {
return this.state.projects.map(currentproject=> {
return <Budget project={currentproject} filter= {this.filterIssues} key={currentproject._id} stop={this.stopPropagation} modal={this.state.modal} toggle={this.toggle}/>;
})
}
My issue comes from the filterIssues function which is used to filter through the state and retrieve some values. Posted below.
filterIssues (id, sprint) {
let filteredIssues = this.state.jiras
.filter( issue => issue.fields.project.key === id )
.filter( issue => issue.fields.sprint.name === sprint )
let sum = 0;
for (var i = 0; i < filteredIssues.length; i++) {
sum += filteredIssues[i].fields.timetracking.originalEstimateSeconds
}
sum /= 3600;
console.log(sum)
return sum;
}
Now I am using the function to retrieve a value for each in the Budget element like so.
const Budget = props => (
<tr onClick={() => props.toggle(props.project._id)}>
<td>£{((props.project.proposedBudget / 4) *1000) }</td>
<td>{() => props.filter(props.project.project, "APP" + 74)}</td>
<td>{() => props.filter(props.project.project, "APP" + 75)}</td>
</tr>
)
The problem is that for every
Functions are not valid as a React child. This may happen if you
return a Component instead of from render. Or maybe you
meant to call this function rather than return it.
Not exactly sure what I am doing wrong. Function works fine on its own outside the Budget component.

How to add case insensitive sorting in react table?

By default, react table sorting is case sensitive.
In order to make it insensitive we have to write a custom sort function.
I like this answer from https://github.com/react-tools/react-table/issues/335.
This would help.
For case insensitive and numbers sorting pass sortTypes in table props like this:
useTable({
sortTypes: {
alphanumeric: (row1, row2, columnName) => {
const rowOneColumn = row1.values[columnName];
const rowTwoColumn = row2.values[columnName];
if (isNaN(rowOneColumn)) {
return rowOneColumn.toUpperCase() >
rowTwoColumn.toUpperCase()
? 1
: -1;
}
return Number(rowOneColumn) > Number(rowTwoColumn) ? 1 : -1;
}
}
})
//function to sort the results
function filterCaseInsensitive(filter, row) {
const id = filter.pivotId || filter.id;
return (
row[id] !== undefined ?
String(row[id].toLowerCase()).startsWith(filter.value.toLowerCase())
:
true
);
}
// react table code goes here
<ReactTable
data={data}
columns={columns}
filterable
defaultFilterMethod={(filter, row) => filterCaseInsensitive(filter, row) }
/>
The question mentions sorting but links to filtering. For custom sorting the app's owner mentions on Github to pass a sortTypes: { alphanumeric: MyCustomFunc } in the table props, like this:
useTable({
columns,
sortTypes: {
alphanumeric: (row1, row2, columnName) => {
return compareIgnoreCase(
row1.values[columnName],
row2.values[columnName]
)
},
},
},
useSortBy
)
The proper way to sort a column with react-table and with a case-insensitive approach, would be to use sortType on a column and then provide a custom function.
/**
*
* React Table helper to sort tables
* with case-insensitive support
*
*/
export const customInsensitiveCompare = (
rowA: Row,
rowB: Row,
columnId: string,
desc: boolean
) => {
const valueA = rowA.values[columnId].toLowerCase();
const valueB = rowB.values[columnId].toLowerCase();
if (desc) {
return valueA.localeCompare(valueB) > 0 ? 1 : -1;
}
return valueB.localeCompare(valueA) > 0 ? -1 : 1;
};
If you do not use Typescript just remove the types and everything will work fine. Take care that we need to return only -1 or 1 and localeCompare sometimes can return 0 or even different values according to MDN docs, that why we assign only -1, 1 as react-table expects.
(firstRow, secondRow, accessor) => {
// get from lodash
const firstValue = get(firstRow.values, accessor, '');
const secondValue = get(secondRow.values, accessor, '');
return firstValue > secondValue ? 1 : -1;
}
Above is the solution I used to assign to "alphanumeric", which covered both cases. Because, as in many programming languages, strings are compared lexicographically hence we need not change the case. And even comparing with numbers works fine.

Compare dates in jsx

I am trying to display events for the same day by comparing dates.
How can I use a conditional statement in my map?
{events && events.length && events.map((event) => <Text>{event.author}
{
(currentDay == date)
? 'same'
: 'different'
}
</Text>)
}
How would be the best way to do this?
You can always use isSame from momentjs
moment(currentDay).isSame(date, 'day')
If you need to do a lot of checks to do in your map, remember you can write it like this as well
events.map((event) => {
const text = // your conditional stuff
// some more code if necessary
return (
<Text>{text}</Text>
)
}

Getting an error when add i++ react js es6 jsx

I am getting an error when adding additional line to code (i++), i would like to know where the code should be added.
let i = 1;
this.props.client_name.split(",").map((entry0) => (
this.props.campaign_name.split(",").map((entry1) => (
this.props.adset_name.split(",").map((entry2) => (
( item.client_name.toLowerCase().indexOf(entry0.toLowerCase()) !== -1 && item.campaign_name.toLowerCase().indexOf(entry1.toLowerCase()) !== -1 && item.adsets_name.toLowerCase().indexOf(entry2.toLowerCase()) !== -1 )?
**i++**
(<Task key={item._id} id={item.adsets_id} i={key} item={item} date_from={this.state.date_from} date_to={this.state.date_to} campaign_name={this.state.campaign_name} adset_name={this.state.adset_name} />)
:
(null)
))
))
))
Thanks
Because you are using two expression here:
condition? i++ (<Task ..../>) : null;
Wrap them in (), Write it like this:
condition? (i++, <Task ..../>) : null;
First it will increment the value of i, then return the Task component.
Check MDN Doc for more details about ternary operator.
Check this snippet:
var a = 1;
var b = true? (a++, a): 0;
console.log('b', b);

Resources