how can i Fetching Data and Updating State with Hooks? - javascript

i have a var resourcesData with 5 empty arrays and 3 arrays with objects of data i'm not sure how can i pass that 3 arrays with object of data into useState and manage it
const resourcesData = data;
i try something like this
const [datos, setDatos] = React.useState(resourcesData);
but if i log datos it return me only empty arrays with no the 3 arrays with objects of data so do you know what i'm doing wrong or how can i manage the state of that 3 arrays with objects ?

By the time you are calling this statement const [datos, setDatos] = React.useState(resourcesData); data has not been loaded that's why you are getting empty array.
So for that purpose you can use a useEffect, like this:
const [datos, setDatos] = React.useState([]);
React.useEffect (()=>{
setDatos(resourcesData);
// if you want to get only the non empty arrays
// you can do it like this:
const FilteredData = resourcesData.filter((arr) => arr.length > 0);
setDatos(resourcesData);
},[resourcesData]);

Related

JavaScript Objects filtering out specific property names

I am creating a filter for a diagram. Whenever a filter is clicked it should remove that category from the diagram. The api call returns an object with names. let’s say the object returns 40 items and I want to filter 5 out by name. What is the best way to approach this?.
I tried to manually type the property names into an array and run the .filter on my object like below. However it returns the entire object unfiltered.
filterDiagram() {
Const array = [“all the names of the properties I want to filter out”]
carbonates = array.forEach(x) => {console.log(x)}
Const filterCat = data.filter (io =>
io.name !== carbonates)
}
Let's say, the array consists of all the names/categories you want to take out.
const toBetakenOut = ['fruits','salts', 'etc' ]
// Please make sure they are not 1 string but rather comma-separated values.
You can filter the API data by using the filter function on the data,to remove objects with names that are within toBetakenOut.
const filterCat = data.filter (io => !toBetakenOut.includes(io.name))
function filterDiagram(){
const dontWantsArray = [/*all of the things you dont want*/];
// Outputs an array of keys
const filteredKeys = Object.keys(yourJSObject)
.filter(key => !dontWantsArray.includes(key));
// After you found the keys you can get the values to another array by keys
const filteredValues = filteredKeys.map(key => yourJSObject[key]);
}

filter and map in an object array

I can't retrieve the user by his customer number. I use the includes function in filter, but this returns the error: Cannot read properties of null (reading 'includes') . Despite everything I've seen on the forum, nothing solves my problem. I have an array of user object, so I make a map on the array and then I filter here is my code:
thank you very much for help
const ClientComponent = ()=>{
const resultSearchClient = useSelector((state)=> state.reducerSearchCriteria)
const datasClientService = useSelector((state)=> state.reducerClientAdmin.state)
const newArray = datasClientService.map(val=>{ return val})
const filterArray = newArray.filter(u => {return u.number_client.includes(resultSearchClient)})
return(
<div>
<p>{filterArray} </p>
</div>
)
}
export default ClientComponent;
The error that you are receiving is thrown because number_client is null (instead of an array or string that you are expecting there).
If you know that number_client is nullish, you can do:
const filterArray = newArray.filter(u =>
return (u.number_client ?? '').includes(resultSearchClient)
})
If you expect a value everytime there, then there is a different problem with your data.
Also, what is the purpose of newArray? that map does nothing except for creating a shallow clone, right? If you neeed a shallow clone, you can just do const newArray = [...datasClientService]. But from what you sent here, newArray is not even needed. You can just create filterArray based on dataClientService since Array.filter method returns a new array.

How to add and update objects into array of objects?

I am trying to dynamically add an object to an array of objects, I have been trying to Destructuring the main object but it adds a number to the end of the parent array. This is what I have:
const [data, setData] = useState ([
{
_id:1,
firstName:'Leo',
lastName:'Miller',
telephone:'+569273829',
mail:'leo.miller#gmail.com',
work:[
{_id:1, startWorkDate:'01/01/2015', endWorkDate:'01/02/2017', work:'description...'},
{_id:2, startWorkDate:'01/01/2018', endWorkDate:'01/02/2020', work:'description...'}
]
}];
I generate dynamically this object:
const value = {_id:3, startWorkDate:'01/01/2018', endWorkDate:'01/02/2020', work:'description...'}
I need to add it into data.work and after that update only the description of work._id[3]
I try with this function
const addNewWork = (value) => {
let copyData = [...data, data[0].workExperience.push(value)]
return setData(copyData)
}
but for some reason doesn't add correctly the object. Help please!
You have an array and not an object. Your statement
let copyData = [...data, data[0].workExperience.push(value)]
is doing two things:
mutating the state by doing push(). Which is not the react way.
creating a new array. Also adding a new item to the array, but that is the new length of data[0].workExperience.
The return value of Array.prototoype.push is:
The new length property of the object upon which the method was called.
What you have to do is:
Make a copy of the array. Can use ... (spread operator) here.
Make a copy of the array object you want (first index). Try to add the object to its specific property workExperience.
const addNewWork = (value) => {
let newData = [...data];
let newWorkExperienceArray =
[...data[0].workExperience,value];
let newDataFirstObject = {...data[0], workExperience : newWorkExperienceArray};
newData[0] = newDataFirstObject;
return setData(newData)
}
You can also update the property. I didn't find the relevant code in your question as to what I have to update so I didn't update anything in the third workExperience object.
EDIT: It seems in your code the property name is work and not workExperience. Please confirm. The above code uses workExperience, you can replace it by work if that is the case
You can do this with this simple function:
const addNewWork = (value) => {
let updatedObj = data[0];
updatedObj.work.push(value)
// updates your object each time
let copyData = [updatedObj]
// adds a new object for each call
// let copyData = [...data, updatedObj]
return setData(copyData)
}
Now it updates the object in your state. If you want to add a new object for each call just uncomment let copyData = [...data, updatedObj] and comment out let copyData = [updatedObj]
When you set state for array your setter is a quite bite different
setData(prevData => [...prevData, newItem]) // to add a single item to array
setData(prevData => newArray) // to replace entire array

Getting Values from comparing Two Arrays

I have two array one is the state like this
const [state,setState] = useState([])
and the another one is am getting from a form when it is submitted;
ids = [4,5,6]
setState(ids)
Now, when i update the state second time the values are there i.e 4,5,6 in the state.
so the values are getting duplicated ie 4,5,6,4,5,6
What i want is to make sure that only the elements which is not present in the array gets pushed not all,and i get the valid output like following.
4,5,6,7
If 7 is added.
What i did is like this, which is totally wrong
const filterss = [...state];
setState([]);
filterss.push(values);
setState(filterss);
const ids=[4,5,6]
let formSubmitIds=[4,5,6,7]
let uniquieIds=[...new Set([...ids,...formSubmitIds])]
console.log(uniquieIds)
Simply use this logic to setState accordingly i.e setState(uniquieIds)
ids are the stored values in state
formSubmitIds is the new array which you are getting on submit of form
[...ids,...formSubmitIds] will merge both arrays
Set is used to remove duplicates
[......new Set] will convert Set back to an array with unique ids only
const filters = [...state];
values.forEach(item => {
if (filters.indexOf(item) < 0) {
filters.push(item);
}
})
setState(filters);
First push all the old and new values in a single array then try using Set() to get unique values in the array.
Here's the code.
setState(new Set(arrayName))
Use Set() constructor to achieve your goal.
Try:
const [state, setState] = useState([])
const ids = [4,5,6]
const formSubmittedIds = [4,5,6,7]
setState([...new Set([...ids, ...formSubmittedIds])]) // Sets [4, 5, 6, 7] to the state
Happy coding :)

React hooks useState/setState not working after sorting the array and passing it

I have React app and I am using React hooks:
const [companies, setCompanies] = useState([]);
I am fetching the data and 'companies' is getting filled with data. I also have another button for sorting the data by NetIncome:
const sortByIncome = e => {
const el = document.getElementById("sort-selectbox");
const arr = companies.sort((a, b) => (a.NetIncome > b.NetIncome ? -1 : 1));
console.log(arr);
setCompanies(arr);
};
The problem is that setCompanies does not re-renders. In the console.log I can see that array is sorted correctly and even if I console.log(companies) I can see that it is also sorted. But noting happens in the interface. Also if I type the same code:
const sortByIncome = e => {
const el = document.getElementById("sort-selectbox");
const arr = companies.sort((a, b) => (a.NetIncome > b.NetIncome ? -1 : 1));
console.log(arr);
setCompanies([]);
};
but pass to setCompanies empty array it immediately works and displays nothing (I have render function that gets companies as param).
So why it is not working with passing arr? Is it because I am passing the same array but just sorted?
Here:
const arr = companies.sort((a, b) => //...
Array.prototype.sort sorts array in place, that is, mutates the original object. The reference doesn't change, and the mutation doesn't get noticed. Do instead
const arr = [...companies].sort((a, b) => //...
The value of the hook-variable companies inside the function sortByIncome will always be the initial value of your hook ([]) and will never receive the new value set by using setCompanies.
A solution to your problem is to wrap your function sortByIncome in a useCallback hook with the hook-variable companies as a dependency. This will ensure that the function always uses the current value of companies.
const sortByIncome = React.useCallback(e => {
// Using `companies` will always result in the current value
}, [companies]);
useCallback documentation

Categories

Resources