Optimize the display value in React Js - javascript

Please let me know how I can optimize more below code in one line:
{addressToDisplay?.addressLineOne}
{addressToDisplay?.addressLineTwo}
{addressToDisplay?.city}
{addressToDisplay?.state}
{addressToDisplay?.zip}

if your object is already well organized you can do this
return <>{[...Object.values(addressToDisplay || {})].join` `}</>;
Or else you have this kind of solution
const {addressLineOne, addressLineTwo, city, state, zip} = addressToDisplay || {};
return <>{[addressLineOne, addressLineTwo, city, state, zip].join` `}</>

You can try this out:
Object.keys(addressToDisplay).map(function(key) {
return <>{ addressToDisplay[key] }</>
})
And to display both key, value you can add:
Object.entries(addressToDisplay).map(([key, val]) =>
<h2 key={key}>{key}: {val}</h2>
)
If you need specific values then you can store the keys which you need in one array
addressField = ['city', 'state', 'lineone', 'linetwo']
and then get them by
{addressToDisplay && addressField.map(key => <>{addressToDisplay[key]}</>)}

{addressToDisplay &&
addressField.map((key) => <>{addressToDisplay[key]}</>)}

Related

react on change check if equal to array of object

i have input and array of object
i need when i type it will display the object. "airplaneCompany" is the object property that i need to compare
i was doing only if the input is equal to the "airplaneCompany" it will return it by the filter method
but i need for evrey char it will check it and if the object start with "a" it will show this object
const [txtInp, setTxtInp] = useState("");
const showFlight = users.filter((user) => {
return user.airplaneCompany == txtInp;
});
{showFlight.map((user, index) => {
const { id, airplaneCompany, passenger } = user;
return (
<div className="flightContainer" key={index}>
<div>{id}</div>
<div>{airplaneCompany}</div>
<div>{passenger}</div>
</div>
);
})}
You can use #Patrick answer, but JavaScript has its own startsWith function you can use.
Also, consider wrapping the filter with the useMemo hook to run it only when the input changes and not on every render.
const showFlight = useMemo(() => {
return users.filter((user) => {
return user.airplaneCompany == txtInp;
});
}, [txtInp]);
I think you can use your .filter function to check if the airplaneCompany starts with the user input?
Something like
return user.airplaneCompany.indexOf(txtInp) === 0;
just use regex. just place input value like /^airplaneCompany$/
const wrongInputText = 'q'
const rightInputText = 'airplaneCompany'
console.log('wrong', 'return value=', /^airplaneCompany$/.test(wrongInputText))
console.log('right', 'return value=',/^airplaneCompany$/.test(rightInputText))

React hooks removing item from an array and add it to another array

export default function ShoppingCart() {
const classes = useStyle();
const {
productsList, filteredProductsList, setFilteredProductsList, setProductsList,
} = useContext(productsContext);
const [awaitingPaymentList, setAwaitingPaymentList] = useState([]);
const [addedToCartList, setAddedToCartList] = useState([]);
const addToCartHandler = useCallback((itemId) => {
const awaitingPaymentListIds = awaitingPaymentList.map((item) => item.id);
const isInAwaitingPaymentList = awaitingPaymentListIds.includes(itemId);
isInAwaitingPaymentList ? setAddedToCartList([...addedToCartList, addedToCartList.push(awaitingPaymentList[awaitingPaymentList.findIndex((item) => item.id === itemId)])]) : setAddedToCartList([...addedToCartList]);
isInAwaitingPaymentList
? setAwaitingPaymentList(awaitingPaymentList.splice(awaitingPaymentList.findIndex((item) => item.id === itemId), 1))
: setAwaitingPaymentList([...awaitingPaymentList ])
setProductsList(awaitingPaymentList);
}, [addedToCartList, awaitingPaymentList, setProductsList]);
useEffect(() => {
setFilteredProductsList(
productsList.filter((product) => product.status === 'AWAITING_PAYMENT'),
);
}, [productsList, setFilteredProductsList, setFilteredProductsList.length]);
useEffect(() => {
setAwaitingPaymentList(filteredProductsList);
}, [filteredProductsList]);
I manage to delete the item from awaitingPaymentList and to add it into addedToCartList but looks like I am doing something wrong because it is adding the object, but the previous ones are replaced with numbers :). On the first click, the array is with one object inside with all data, but after each followed click is something like this => [1,2,3, {}].
When I console log addedToCartList outside addToCartHandler function it is showing an array: [1] :)))
Since there is some code I hope I am not going to receive a lot of negative comments like last time. And if it's possible, to give me a clue how to make it for all items to be transferred at once, because there will be a button to add all. Thank you for your time.
I think this line of code is causing issue:
isInAwaitingPaymentList
? setAddedToCartList([
...addedToCartList,
addedToCartList.push(
awaitingPaymentList[
awaitingPaymentList.findIndex((item) => item.id === itemId)
]
)
])
: setAddedToCartList([...addedToCartList]);
array.prototype.push returns the new length of the array that you are pushing into, this is likely where the incrementing element values are coming from. The push is also a state mutation.
It is not really clear what you want this code to do, but I think the push is unnecessary. Perhaps you meant to just append the last element into the new array you are building.
isInAwaitingPaymentList
? setAddedToCartList([
...addedToCartList, // <-- copy state
awaitingPaymentList[ // <-- add new element at end
awaitingPaymentList.findIndex((item) => item.id === itemId)
]
])
: setAddedToCartList([...addedToCartList]);
Suggestion
If you simply want to move an element from one array to another then find it in the first, then filter it from the first, and copy to the second if it was found & filtered.
const itemToMove = awaitingPaymentList.find(item => item.id === itemId);
setAwaitingPaymentList(list => list.filter(item => item.id !== itemId));
itemToMove && setAddedToCartList(list => [...list, { ...itemToMove }])

ngx dropdown list get selected values

I am trying to use ngx dropdown list like this:
<ngx-dropdown-list [items]="categoryItems" id="categoriesofdata" [multiSelection]="true"
[placeHolder]="'Select categories'"></ngx-dropdown-list>
And I am getting all selected values like:
get selectedCategories() {
const items = this.categoryItems.filter((item: any) => item.selected);
return items.length ? JSON.stringify(items.map(item => ({
value: item.value
}))) : '';
}
and output looks like:
[{"value":"Surname"},{"value":"Address"}]
I want to get only for example Surname instead of value and Surname.
[0].value
How Can I do this?
Should I use for loop or is better option?
I think you're almost there, in fact you're doing a little too much. Your map function should just return the value you are interested in rather than creating a new structure.
get selectedCategories() {
const items = this.categoryItems.filter((item: any) => item.selected);
return items.length ? JSON.stringify(items.map(item => item.value)) : '';
}
Edit:
And as a personal preference, I would refactor to something like this:
get selectedCategories() {
if (!this.categoryItems.length) {
return '';
}
const surnames = this.categoryItems
.filter(item => item.selected)
.map(item => item.value);
return JSON.stringify(surnames);
}
I prefer to get out of a function early in the case where no further processing is required. And I would return the result of chained filter and map functions into a new surnames variable. The named variable signals the intention of the code, and keeps the array logic together.
This is just my preference though. Your code was almost there functionally.

Filter table data

I want to filter a table based on few conditions .. Below is the sample image
code I've tried
this.reportData.filter(it => {
if (
it.startTimeFilter.includes(this.startdatefilter) &&
it.endTimeFilter.includes(this.enddatefilter) &&
it.status.toLowerCase().includes(this.status)
) {
this.filteredData.push(it);
}
});
Ok, I can give you some hint to achieve this as I do not have full code. Make sure this.reportData is never changed as we need all data to have filtering
applyFiltering(){
this.dataToShowOnUI = getFilteredData();
}
getFilteredData(): any[]{
let filteredData = JSON.parse(JSON.stringify(this.reportData));
if(this.startdatefilter && this.enddatefilter){
filteredData = filteredData.filter(it =>
it.startTimeFilter.includes(this.startdatefilter) &&
it.endTimeFilter.includes(this.enddatefilter)
);
}
if(this.status){
filteredData = filteredData.filter(data => data.status.toLowerCase().includes(this.status))
}
if(this.operatingSystem){
filteredData = filteredData.filter(data => data.operatingSystem.toLowerCase().includes(this.operatingSystem))
}
// and so on ...
return filteredData;
}
I'm assuming that this.reportData and this.filteredData are arrays. Then the correct way of using filter method is the following:
this.filteredData = this.reportData.filter(it =>
it.startTimeFilter.includes(this.startdatefilter) &&
it.endTimeFilter.includes(this.enddatefilter) &&
it.status.toLowerCase().includes(this.status)
);
Basically, the parameter of filter should be a function that returns boolean value (which tells if the element should be kept as result), and it returns the filtered new array without modifying the given one.

if statement in a mapping

Currently I'm getting a
continue must be inside a loop
which I recognize as a syntax error on my part because it should be fixed.
Will fixing this to retain this logic in an if statement work with the mapping?
sales = data.map(function(d) {
if (isNaN(+d.BookingID) == false && isNaN(+d["Total Paid"]) == false) {
return [+d.BookingID, +d["Total Paid"]];
} else {
continue;
}
});
map is meant to be 1:1.
If you also want filtering, you should filter and then map
sales = (
data
.filter(d => (!isNaN(+d.BookingID)&& !isNaN(+d["Total Paid"]))
.map(d => [+d.BookingID, +d["Total Paid"]];
});
As others have mentioned, you cannot "continue" from within a map callback to skip elements. You need to use filter. To avoid referencing the fields twice, once in the filter, and once in the map, I'd filter afterwards:
sales = data
.map(d => [+d["bookingId"], +d["Total Paid"]])
.filter(([id, total]) => !isNaN(id) && !isNaN(total));
or, to make it easier in case you later want to include additional values in the array:
sales = data
.map(d => [+d["bookingId"], +d["Total Paid"]])
.filter(results => results.every(not(isNaN)));
where
function not(fn) { return x => !fn(x); }
or
function allNotNaN(a) { return a.every(not(isNaN)); }
and the, using parameter destructuring:
sales = data
.map(({bookingId, "Total Paid": total)) => [bookingId, total])
.filter(allNotNaN);

Categories

Resources