I am creating a function for selecting/deselecting checkboxes representing objects in my array.
Currently I have:
selectAll(allType: string, state) {
this.modalData.columnPermissions.forEach(a =>
a["can" + allType] = state
);
}
(allType allows me to target "canRead" or "canWrite" keys depending on which SELECT ALL the user chooses from the top of 2 columns.)
This is working fine - however a scenario has now been introduced where if an object contains the property IDM=TRUE then "canWrite" should always be FALSE
I'm struggling on how to now adapt my selectAll function to exclude any object with a property of IDM=TRUE on the KEY canWrite
Any help is appreciated
I have resolved this with info from depperm
this.modalData.columnPermissions.forEach(a => {
if (allType === 'Write' && !a.IDM) {
a["can" + allType] = state
} else if (allType === 'Read') {
a["can" + allType] = state
}
})
Related
In a React project, I've certain number of records which also contain input fields like Date and Text components in a Grid. I'm processing the date and text values in save function. All the records are fetched from JSON data, while saving date values its assigned to new key object but new one isn't getting updated with the old one. I have seen many similar posts but, none useful. Please refer to the code below:
Following is the function where I'm extracting both text and date values
const updateGrid = (data) => {
if (Array.isArray(allData) && allData?.length > 0) {
const tempData = allData;
tempData.map(x=> {
if(data.id === x.id) {
x.name = data.textVal
}
// Here I'm assigning the 'Establish' value with 'est'
if(data.id === x.id) {
x['est'] = x['Establish']
x.Establish = data.dateVal
}
})
setDataAll(tempData)
}
console.log('tempdataNew', dataAll)
}
As you can see from above picture, we have two keys, 'est' and 'Establish', but, I need only 'Establish', also getting undefined on 'name' when changed date value and vice-versa. What could be the best optimal solution to tackle this issue?
Please refer to Codesandbox --> https://codesandbox.io/s/jovial-aryabhata-95o2sy?file=/src/Table.js
Hello I am new to programming and I am trying to make a function in React that adds a team to an array of selected teams but only if there are less than 2 teams selected and if the team is available (not already chosen). It is working to limit the array to only 2 values but the array will accept the same team twice and I am not sure why. For example if the user clicks ATL twice then that team will be in the array twice. What did I do wrong here and what should I change in order to fix it? Sorry if the question is too simple for this forum, I am new.
Here is the code where I am changing the state and checking if gameState.selected_teams[0] != team:
function App() {
const [gameState, setGameState] = useState({
cards: Cards,
selected_teams: []
});
function setTeam(team){
if (gameState.selected_teams.length < 2 && gameState.selected_teams[0] != team) {
setGameState((prevState) => ({
cards: prevState.cards,
selected_teams: [
...prevState.selected_teams, {
team
}
]
}))
}
}
And for the component that calls the setTeam function:
function TeamSelect({cards, setTeam}) {
var teams = Object.keys(cards);
return (
<div className='flex-container'>
<div className='team-container'>
{
teams.map(team => (
<div
onClick={() => setTeam(team)}
className='team-label' key={team}>
{team}
</div>
))
}
</div>
</div>
)
}
You're adding an object {team: team} to your selected teams array each time you perform your click here:
selected_teams: [
...prevState.selected_teams, {
team
}
]
but your team key that you pass into your setTeam function is a string, so your comparison fails as you're trying to compare a string with an object. You can change your comparison to extract the team property from your object:
gameState.selected_teams[0]?.team != team
The ? ensures that a value exists at index 0 in your array before using .team on it (otherwise you would get an error if it's undefined).
You can adapt this code to handle more than one object by using .every() to check that all objects in selected_team's aren't equal to the one you're adding:
if(gameState.selected_teams.length < 2 && gameState.selected_teams.every(obj => obj.team != team)
If you don't need to pass an object {team: team} (as an object with one property doesn't add much value), then you can simply push your team string into your selected teams, and use .includes() to check if the team you're adding already exists in the array:
selected_teams: [
...prevState.selected_teams, team
]
you can then update your condition to use .includes():
if(gameState.selected_teams.length < 2 && !gameState.selected_teams.includes(team))
i'm working on a corona data app for school and I want to sum the amount of tests and positive results from an API.
Here is my code:
function GetDataApi() {
if(data !== null) {
const filter = data?.filter((item => item.Date_of_statistics === '2021-04-01'));
filter.forEach((item, index) => {
setUseTestedResult(parseInt(useTestedResult) + parseInt(item.Tested_with_result));
setUsePositiveData(parseInt(usePositiveData) + parseInt(item.Tested_positive));
});
}
}
It only returns the numbers of the last object in the array. It looks like the setState function isn't working.
State updates are asynchronous. You're repeatedly updating your state, overwriting previous updates, so you end up storing only the result of the last call to your state setters.
Instead, build the sum, then set the result:
function GetDataApi() {
if (data !== null) {
// No ? here −−−−−−−−−−−−v
const filteredData = data.filter((item => item.Date_of_statistics === '2021-04-01'));
let testedSum = 0;
let positiveSum = 0;
for (const {Tested_with_result, Tested_positive} of filteredData) {
testedSum += Tested_with_result;
positiveSum += Tested_positive;
}
setUseTestedResult(previousValue => previousValue + testedSum);
setUsePositiveData(previousValue => previousValue + positiveSum);
}
}
A couple of notes:
I've removed the parseInts, hopefully the data you're using is already numeric, but add them back if you need them. Only parse strings, don't call parseInt on numbers.
Note that I replaced the optional chaining (?.) with normal chaining (.), since you've just tested that data isn't null and if it's undefined, your subsequent code would fail anyway.
Your code was adding the sum from data's entries to the existing state member's value, so that's what I've done above, using the callback form of the state setters (since any time you use existing state to set new state, you should use the callback form). But to me it seems a bit odd to be adding this information to an existing state member, rather than replacing it.
I have an interface:
export interface ISchoolsPreview {
// Shared
AgeID: string;
School_name?: string;
}
I have a function triggered by a change in a Checkbox:
onChange(code: string, name: string, check: boolean): void {
const tempPreview: ISchoolsPreview = {AgeID: code, School_name: name};
if (check) {
this.schoolsPreview.push(tempPreview);
} else {
//This is where the error lies
const index = this.schoolsPreview.indexOf(tempPreview);
if (index > -1) {
this.schoolsPreview.splice(index, 1);
}
}
}
Check is defined by whether the checkbox was checked or uncheched. If checked it adds a new element of ISchoolsPreview to schoolsPreview. This works and when I step through it shows up and displays correctly on my front end.
However when I uncheck a checkbox, the indexOf(tempPreview) always returns -1 even if I am passing the same entry.
How do I correctly remove an element from my Interface List
You should always find the index of the object based on some property in the object rather than using the whole object itself as follows.
const index = this.schoolsPreview.findIndex((obj) => obj['Property'] === code);
If you thing you will have duplicate codes in the array, then you might have to generate unique ids for each objects and search based on that Id.
Note: I am not sure on this, but passing object to index while return true only if the object references to the same memory. If its a new object you are trying to find, which is in new memory, it might return false. Someone can correct me on this.
I have fixed this by changing:
const index = this.schoolsPreview.indexOf(tempPreview);
to:
const index = this.schoolsPreview.findIndex(s => s.AgeID === code);
I'm currently writing a little function to take a $scope value from an input field, then add it to a new array containing invited users.
To prevent duplicate entries into the array I'm trying to use JavaScript's filter method.
My problem is when I look at whats being output to the console, the console.log inside the filter function always prints the same Email value, it doesn't seem to update and consider the new input. e.g. a user has added 2 users, the first will be added and the invitesArr will only contain the first Email.
var invitesArr = $scope.invites;
console.log(invitesArr)
console.log($scope.searchContacts)
if ($scope.invites.length >= 0) {
invitesArr.filter(function(invitesArr) {
console.log(invitesArr.Email)
return invitesArr.Email === $scope.searchContacts;
});
if (invitesArr == false) {
courseAccountService.inviteGuestToCourse($scope.courseId,$scope.searchContacts).
then(function(invitation) {
$scope.invites.push(invitation);
});
}
}
Try the below code:
var invitesArr = $scope.invites;
console.log(invitesArr)
console.log($scope.searchContacts)
if ($scope.invites.length >= 0) {
//use arrow operator instead of function.
var duplicateEmails = invitesArr.filter((item) => {
console.log(invitesArr.Email)
//assuming datatype of item.Email and $scope.searchContacts are same else use == for comparision
return item.Email === $scope.searchContacts;
});
//Check for length and then push to your invites
if (duplicateEmails.length==0) {
courseAccountService.inviteGuestToCourse($scope.courseId,$scope.searchContacts).
then(function(invitation) {
$scope.invites.push(invitation);
});
}
}
Hope it helps!!