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))
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]}</>)}
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 }])
I have an array of some class names that all of the values in that array end with numbers. I want to have a function that when I give it a number, it search through that array, and check the last 3 digits of each value, to find the matching number and return that matching value.
So lets say, I give it value 200 and it searches through the array and returns wi-owm-200.
I manage to make it but it does not return it. It does find the value, but when it is outside of the function, it returns 'undefined'.
Here is my code: Fiddle
var owmIcon = ["wi-owm-200", "wi-owm-201", "wi-owm-202", "wi-owm-210", "wi-owm-211", "wi-owm-212", "wi-owm-221", "wi-owm-230", "wi-owm-231", "wi-owm-232", "wi-owm-300", "wi-owm-301", "wi-owm-302", "wi-owm-310", "wi-owm-311", "wi-owm-312", "wi-owm-313", "wi-owm-314", "wi-owm-321", "wi-owm-500", "wi-owm-501", "wi-owm-502", "wi-owm-503", "wi-owm-504", "wi-owm-511", "wi-owm-520", "wi-owm-521", "wi-owm-522", "wi-owm-531", "wi-owm-600", "wi-owm-601", "wi-owm-602", "wi-owm-611", "wi-owm-612", "wi-owm-615", "wi-owm-616", "wi-owm-620", "wi-owm-621", "wi-owm-622", "wi-owm-701", "wi-owm-711", "wi-owm-721", "wi-owm-731", "wi-owm-741", "wi-owm-761", "wi-owm-762", "wi-owm-771", "wi-owm-781", "wi-owm-800", "wi-owm-801", "wi-owm-802", "wi-owm-803", "wi-owm-804", "wi-owm-900", "wi-owm-901", "wi-owm-902", "wi-owm-903", "wi-owm-904", "wi-owm-905", "wi-owm-906", "wi-owm-957"];
var res = findOWMIcon("200");
console.log(res);
function findOWMIcon(num) {
$.each(owmIcon, function(key, value) {
var classNum = value.substr(value.length - 3);
if (parseInt(num, 10) === parseInt(classNum, 10)) {
console.log(value);
return value;
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Any idea how to solve it? So I can get the found value outside the function?
This is sufficient:
owmIcon.filter(e => e.slice(-3) == "200");
// Get all elements that ends in "01"
items = get_all_items().filter(e => e.slice(-2) == "01");
console.log(items);
function get_all_items(){
return ["wi-owm-200", "wi-owm-201", "wi-owm-202", "wi-owm-210", "wi-owm-211", "wi-owm-212", "wi-owm-221", "wi-owm-230", "wi-owm-231", "wi-owm-232", "wi-owm-300", "wi-owm-301", "wi-owm-302", "wi-owm-310", "wi-owm-311", "wi-owm-312", "wi-owm-313", "wi-owm-314", "wi-owm-321", "wi-owm-500", "wi-owm-501", "wi-owm-502", "wi-owm-503", "wi-owm-504", "wi-owm-511", "wi-owm-520", "wi-owm-521", "wi-owm-522", "wi-owm-531", "wi-owm-600", "wi-owm-601", "wi-owm-602", "wi-owm-611", "wi-owm-612", "wi-owm-615", "wi-owm-616", "wi-owm-620", "wi-owm-621", "wi-owm-622", "wi-owm-701", "wi-owm-711", "wi-owm-721", "wi-owm-731", "wi-owm-741", "wi-owm-761", "wi-owm-762", "wi-owm-771", "wi-owm-781", "wi-owm-800", "wi-owm-801", "wi-owm-802", "wi-owm-803", "wi-owm-804", "wi-owm-900", "wi-owm-901", "wi-owm-902", "wi-owm-903", "wi-owm-904", "wi-owm-905", "wi-owm-906", "wi-owm-957"];
}
Use function(e){ return e.slice(-3) == "200"; } instead of e => ... if you care about backward compatibility (ES5 and before).
let data = ["wi-owm-200", "wi-owm-201", "wi-owm-202", "wi-owm-210", "wi-owm-211", "wi-owm-212", "wi-owm-221", "wi-owm-230", "wi-owm-231", "wi-owm-232", "wi-owm-300", "wi-owm-301", "wi-owm-302", "wi-owm-310", "wi-owm-311", "wi-owm-312", "wi-owm-313", "wi-owm-314", "wi-owm-321", "wi-owm-500", "wi-owm-501", "wi-owm-502", "wi-owm-503", "wi-owm-504", "wi-owm-511", "wi-owm-520", "wi-owm-521", "wi-owm-522", "wi-owm-531", "wi-owm-600", "wi-owm-601", "wi-owm-602", "wi-owm-611", "wi-owm-612", "wi-owm-615", "wi-owm-616", "wi-owm-620", "wi-owm-621", "wi-owm-622", "wi-owm-701", "wi-owm-711", "wi-owm-721", "wi-owm-731", "wi-owm-741", "wi-owm-761", "wi-owm-762", "wi-owm-771", "wi-owm-781", "wi-owm-800", "wi-owm-801", "wi-owm-802", "wi-owm-803", "wi-owm-804", "wi-owm-900", "wi-owm-901", "wi-owm-902", "wi-owm-903", "wi-owm-904", "wi-owm-905", "wi-owm-906", "wi-owm-957"];
// Suppose you want to get all elements that end with 200, so...
let filteredData = data.filter(item => item.slice(-3) === "200");
console.log(filteredData);
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);