I have the following line:
<button className={`actionBoxButton ${props.moves[0].moveName !== "FirstPassMove" && props.moves[0].moveName !== "PassMove" ? "actionBoxButtonGrey" : ''}`}
What it does is to check if the object "moves" has the value "FirstPassMove" for the key moveName. If so, I want it so switch to another style. This is working well.
But what I want to achieve is, to not only check the element 0 of the object, but all the objects and check if there is a moveName "FirstPassMove" in any element of the object.
It is written in React 16.12
Thanks!
You can simplify your jsx by defining a separate function for dynamic className like this:
const check = () => {
let className_ = "";
// if this.props.moves is an array, use of instead of in
for(let i in this.props.moves) {
if((this.props.moves[i].moveName !== "FirstPassMove") && (this.props.moves[i].moveName !== "PassMove")) {
className_ = "actionBoxButtonGrey";
}
}
return className_;
}
<button className={this.check()}>button</button>
props.moves.includes('FirstPassMove')
Assuming your props.moves is an array it will return true or false if this string is inside the props.moves array
If you want to add className in case at least one of your moves has FirstPassMove or PassMove name you should use Array.prototype.some()
const hasPass = moves.some(({ moveName }) => (
moveName === "FirstPassMove" ||
moveName === "PassMove"
));
I am guessing you want to check that all the moves satisfy the constraint, in which case, you can use Array.prototype.every to ensure every move satisfies the constraint. If you only need some moves to satisfy the constraint, you may use Array.prototype.some instead.
// For example
const props = {
moves: [
{ moveName: 'FirstPassMove' },
{ moveName: 'PassMove' },
{ moveName: 'PassMove' },
{ moveName: 'OtherPassMove' },
]
};
function isValidMove({ moveName }) {
return moveName !== "FirstPassMove"
&& moveName !== "PassMove";
}
function getActionBoxButtonClassName(hasColor) {
return `actionBoxButton ${hasColor ? "actionBoxButtonGrey" : ''}`;
}
console.log([
getActionBoxButtonClassName(props.moves.every(isValidMove)),
getActionBoxButtonClassName(props.moves.some(isValidMove))
]);
Related
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))
I have an array of objects in the below format.
let selectedCols =
[
{
"table" :
{
"id" : "bafc1af7-e2c5-ec11-a7b6-00224818a168",
"name" : "test1"
}
visible : true
trueCol : 1
},
{
"table" :
{
"id" : "cdep1af7-e4c5-ec11-a7b6-00224818a198",
"name" : "test2"
}
visible : true
trueCol : 2
}
]
I am creating a copy of the above object in my code and modifying its visible property in the copied object
let copyOfSelectedColsObj = JSON.parse(JSON.stringify(selectedCols ));
copyOfSelectedColsObj.forEach(column => column.visible = false);
Now i only want to copy the value of 'visible' property from copyOfSelectedColsObj back in to my original object wherever the id field is matching.How can i achieve this?
I am quite new to javascript and can't figure out this. Any help would be appreciated
You can use forEach again to iterate over the original array (selectedCols) and when it finds an element with the same id as the current element in the target array (copyOfSelectedColsObj), replace the visible property.
let selectedCols = [{table:{id:"bafc1af7-e2c5-ec11-a7b6-00224818a168",name:"test1"},visible:true,trueCol:1},{table:{id:"cdep1af7-e4c5-ec11-a7b6-00224818a198",name:"test2"},visible:true,trueCol:2}];
let copyOfSelectedColsObj = JSON.parse(JSON.stringify(selectedCols));
const overwrite = () => {
selectedCols.forEach(column => {
// Get the current element id
const tableId = column?.table?.id;
// If the current element id does not exist, no processing is required
if (tableId) {
// Find element matching element id from target array
const filtered = selectedCols.filter(c => c?.table?.id == tableId);
// When the element is found, replace the visible property
if (filtered.length > 0) {
column['visible'] = filtered[0]['visible'];
}
}
return column;
});
}
// Replace all visible with false
copyOfSelectedColsObj.forEach(column => column.visible = false);
overwrite();
console.log('Replace all visible with false', copyOfSelectedColsObj);
// Replace one of the visible with true
copyOfSelectedColsObj[0]['visible'] = true;
overwrite();
console.log('Replace one of the visible with true', copyOfSelectedColsObj);
selectedCols.forEach((column,i) => {
if(column.table.id===copyOfSelectedColsObj[i].table.id) {
column.visible = copyOfSelectedColsObj[i].visible;
}
})
You said wherever the id field is matching, since copied object is replica of original object, don't you think every id would match hence you can set all visible properties to false.
I will suggest to loop one array inside another loop, but only for small arrays.
something like this:
let newSelectedCols = selectedCols.map((i) => {
return {
...i,
visible: copyOfSelectedColsObj.find(
(j) => j.table.id === i.table.id
)?.visible,
};
});
The map will iterate over the original and for each element it will look for the item with the same table.id and (if exists) it will copy the "visible" value.
searchList(array, filters) {
var currentUserId = 125;
var list = array;
// array example [{aisle: A9, userid: 125},{aisle: B2, userid: null},{aisle: C#, userid: 125}]
// filters example {assignedButtonActive: true, unassignedButtonActive: false, aisle: A9}
result = Object.keys(list)
.map((key) => {
return { ...list[key] };
})
.filter((data) => {
// If assigned or unassigned buttons are not active, this filter doesnt apply and aisle should be the only thing filtering
let assigned = filters.assignedButtonActive
let unassigned = filters.unassignedButtonActive
let aisleSelection = filter.aisle;
let aisle = data.aisle;
let userid = data.userid;
return aisle.indexOf(aisleSelection) > -1 // Need a conditional to also filter out assigned/unassigned if the buttons are active, otherwise not needed.
});
return result;
}
I am trying to filter a list with the combination of an input search and button/flags. I have no problem with the input search function filtering and returning the list. The problem Im having is using boolean flags along with the search input to be even more exact on what i want to filter, but I am having an issue on how to return the result using conditionals/booleans in this case. I cant seem to mix the two conditions for a return with both filters applied. I've tried something like this return aisle.indexOf(aisleSelection) > -1 && (assigned) ? assignedTo == currentUserId : (unassigned) ? assignedTo == null : [] but seems I'm way off. For example if either assigned/unassigned flags are active, it will add one of these two filters assignedTo === currentUserId or assignedTo == null to filter along with aisle filter as well, pretty much so they can work together as well, not one or the other
Not looking for the solution written out for me, more on how I can handle this filtering beyond just an input, with the possibility to off more filters being used
Any help/tips would be greatly appreciated
Finish out the function before returning, then have different return statements for each condition
rather than
return aisle.indexOf(aisleSelection) > -1
try
if (aisle.indexOf(aisleSelection) > -1) {
return true}
else if (other possibility){
return true}
else (case to filter out){
return false}
filter gets called on each element in the array, and decides to keep the element if the callback function returns true
Based on what I have understood, follow through this code especially the part I have commented then let me know if this what you wanted. If there's you don't get, let me know.
function searchList(array, filters) {
var currentUserId = 125;
var list = array;
result = Object.keys(list)
.map((key) => ({ ...list[key] }))
.filter((data) => {
let assignedSelection = filters.assignedButtonActive;
let unassignedSelection = filters.unassignedButtonActive;
let aisleSelection = filters.aisle;
let aisle = data.aisle;
let userid = data.userid;
return Boolean(Boolean(assignedSelection) || Boolean(unassignedSelection)) && aisle.includes(aisleSelection)?assignedTo = currentUserId:assignedTo = null;
/**
Explanation:
I am not sure of what you wanted to achieve with this, but follow through and see If this is what you wanted.
1. Boolean(Boolean(assignedSelection) || Boolean(unassignedSelection))
This part will return true if either assignedSelection or unassignedSelection is true.
This part will return false if both assignedSelection and unassignedSelection are false.
2. aisle.includes(aisleSelection)
This part will return true if aisleSelection matches aisle
This part will return false if aisleSelection does not match aisle
3. Boolean(Boolean(assignedSelection) || Boolean(unassignedSelection)) && aisle.includes(aisleSelection)
This part will return true if both part_(1) and part_(2) return true
Thus part will return false if either part_(1) or part_(2) returns false
4. return Boolean(Boolean(assignedSelection) || Boolean(unassignedSelection)) && aisle.includes(aisleSelection)? assignedTo = currentUserId : assignedTo = null;
This part will return null if part_(3) returns false
This part will give the variable assignedTo the value currentUserId if part_(3) returns true
*/
});
return result;
}
//Execute the example
var arrayExample = [
{ aisle: "A9", userid: 125 },
{ aisle: "B2", userid: null },
{ aisle: "C#", userid: 126 },
];
var filtersExample = {
assignedButtonActive: true,
unassignedButtonActive: false,
aisle: "A9",
};
searchList(arrayExample, filtersExample);
in such cases, I use the usual brackets to show the individual parts of the inequality. example
return aisle.indexOf(aisleSelection) > -1 && (assigned) ? assignedTo == currentUserId : ((unassigned) ? assignedTo == null : [])
but maybe
return assignedTo = (aisle.indexOf(aisleSelection) > -1 && (assigned) ? currentUserId : ((unassigned) ? null : []))
I may have misunderstood the necessary conditions. if you describe the conditions in more detail, the answer will be more correct.
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.
I have an array of object something like below
Object[0]
canUpload:false
canBeRemoved:true
type:Object
allowMultiple:false
deleted:false
key:"testValue"
Object[1]
canUpload:true
canBeRemoved:true
type:Object
allowMultiple:false
deleted:false
key:"testValue2"
I want to remove an elements from array which contains key:testValue
var myValues = this.testData.data3;
if(!this.testData.canDownload){
myValues= myValues.filter(function(value){
if(!value.canUpload)
return value.type.key==='testValue';
else return false;
});
But its not removing .Whats the right way to do it?
Here is the full code .I can see myValues array of size 2 .If i print myValues after if block its empty.
Code pen:http://codepen.io/developer301985/pen/woGBNg
If your want to filter your array on the basis of two conditions:
canUpload attr is false
type.key is equal to 'testValue'
so you may want to return false in case of canUpload is true to be as follow:
myValues= myValues.filter(function(value) {
if(!value.canUpload)
return value.type.key === 'testValue';
else return false;
});
Otherwise, you just want to filter on type.key is equal to 'testValue', so it will be as follow:
myValues= myValues.filter(function(value) {
return value.type.key === 'testValue';
});
Note, if the callback function you passed into filter returns true, the element will be kept rather than removed. So in your case, you should return false when the value is testValue.
If I understand you correctly, you want to remove item with value.canUpload==false AND type.key === 'testValue'. Then the negate is value.canUpload || value.type.key !== 'testValue'
var myValues = this.testData.data3;
if (!this.testData.canDownload) {
myValues = myValues.filter(function(value) {
return value.canUpload || value.type.key !== 'testValue';
});
}
Let me know whether it works :)