How to call a variable within a Redux state? - reactjs

How do I call a variable, such as device_id, device_name, or group_id within the device state in Redux?
{JSON.stringify(device.deviceData)} works great and displays all the state information within deviceData, but {JSON.stringify(device.deviceData.device_id)} doesn't show any information.
Given the 0 pin, I also tried {JSON.stringify(device.deviceData.0.device_id)} but this resulted in an error. I wouldn't want to work with that solution anyway though since I want this call to be universal instead of assigning a specific number in that call.
My Redux state is screenshotted below

deviceData appears to be an array. So you may access the first item like this: device.deviceData[0].device_id
How could I make that universal, in pseudo-terms: device.deviceData[all indexes].device_id if I wanted to make a list of the device_id's for example?
You can use array.map to create a new array with only the device_ids.
const device_ids = device.deviceData.map((data) => data.device_id);

Related

Can I access state values from children components in an array?

I'm very new to React, in the process of learning it for a school project. I've tried searching for this answer thinking it'd be a fairly simple solution, but I'm having trouble finding a result that matches my scenario.
Essentially I'm looking to have an array of a specific component (e.g. Child), each holding a value in their state (e.g. { value: 2 } ). I'm looking to iterate through the array, accessing each component's state.value, and calculate a total from it.
My initial thought was to hold the array in the parent's state, and then iterate through the array doing something like this:
this.state.children.map(child => (
child.state.value
))
However, the result is coming back as 'value' being undefined, leading me to believe I can't access another component's state this way.
I also looked into using refs, as described in the following article:
https://www.geeksforgeeks.org/how-to-access-childs-state-in-react/
However, it seems as though that only lets me create a reference to a single child, meaning I would need a new reference for every child component in the array.
Any advice or sample code of what I could do (the more basic the better) would be greatly appreciated!

React - freeze piece of the state?

I have pecuilar input field which on click opens dropdown with checkboxes options. When I type in this input, I need to show only the options that include typed characters. It works fine as I add characters, but as I empty an array of options (which is stored in state), I don't get values back.
I tried freezing piece of state (options), by using Object.freeze, and use this "frozen" array as starting point. But it doesn'r freeze, and I have no clue how to do this. Here's the code
let coppiedOptions = [...state.inputs.names.options];
coppiedInputs.forEach(el => Object.freeze(el));
let newOptions = coppiedOptions.filter(opt => opt.value.includes(action.value));
I am using use Reducer, so I get value as an action payload. And this "newOptions" is being passed into state in reducer
The only solution was writting another options array, with different name, with same data, to coppy it and use it for filtering, while changing only the first one. I quest it is impossible to do with only one set of options. I am an idiot

Array returning as an Object in React Native = can't reference an array item?

I'm using React Native and Open Weather Map API to build a small weather app. The data I retrieve from the API call is more than I want to use so I parse out just the pieces I need and store them in an array. I then take the array and set it to a state object. I can reference the object, but instead of saying my array is an array, it says it's an object, and thus won't let me use any array methods on it. How do I get around this?
//reponseData is the data retrieved from the API call; the data retrieved is an object with arrays and objects
within. The forecast data for the next five days is given in 3 hour increments, so you have a 40 item array of
data pieces. I loop through this list of 40 items, pull out just what I need...
let forecastArray = [];
for (let i=0; i<responseData.list.length; i++) {
let day = responseData.list[i].date
let high = responseData.list[i].weather[0].hiTemp
let low = responseData.list[i].weather[0].loTemp
let condition = responseData.list[i].sys.condition
forecastArray.push(day)
forecastArray.push(high)
forecastArray.push(low)
forecastArray.push(condition)
this.setState({
forecastData: forecastArray
})
When I log, I get an array....
console.warn("forecast is: ", this.state.forecastData)
OUTPUTS: forecast is: ["11-06-2019", 52.5, 47.3, "sunny", "11-06-2019", 63.9, 39.7, "sunny", ...]
Referencing this.state.forecastData[2], for example, however was giving me errors. So I checked the typeof this.state.forecast to see why and it says the array is an Object? I need to further divide out the array data and manipulate it. The first several items (e.x. forecastData[0] through forecastData[9] would be for the forecasted weather for 11-06-2019 at 3pm, ,6pm, 9pm so I need to pull those items, get the highest high and lowest low, etc. I can't do that since I can't even reference the items in the array.
Things I've tried:
using Object.entries and Object.assign methods, but that just splits the items into several arrays, with the first item being the location number and the second item being the array item content. I've tried manipulating the array within the component that uses it, but it still is an Object not an Array, so I can't reference the individual items. The data set is large enough I don't think it would be best practice to push each of the 40+ items into their own state object key.
in Javascript array is a subset of object , i'e it has the same prototype. So typeof Array will be an object. Thats not an issue. Can you update with the error which you are getting while accessing this.state.forecastData[2] coz what i . believe its something not with syntax , rather with the duration of API call.
I would recommend when accessing this.state.forecastData[2] first check if its length is greater than 0 , that way you are sure that there is data inside the array.
constructor(props){
forecastData:[]
}
and when you use it ,
if(this.state.forecastData.length > 0){
this.state.forecastData[2]
}
Try this, and revert with doubts.
Thank you, Gaurav Roy! You were partly correct. The typeof didn't matter at all. But the issue wasn't with the duration of my API, it was that my component was trying to render when it didn't have the data from the API call yet! I put in a conditional
{this.state.forecast !== null && <Forecast forecast=this.state.forecastData />}
and got things working now. Thanks for the quick reply!

why splice not working correctly in react?

I am trying to delete row from my list using delete button .I do like this
if (state.indexOf(action.payload) > -1) {
console.log('iff----')
state.splice(state.indexOf(action.payload), 1);
}
console.log(state)
return state
but it is not deleting the row .here is my code
https://plnkr.co/edit/bpSGPLLoDZcofV4DYxPe?p=preview
Actually using add button I am generating the list of item and there is delete button I am trying to delete item from list using delete button
could you please tell me why it is not working ?
Avoid using Array#splice when working with state in React or Redux. This mutates your state, which you never want to do. Instead, favour immutable methods like Array#slice. e.g.
const index = state.indexOf(action.payload);
if (index === -1) {
return state;
}
return [...state.slice(0, index), ...state.slice(index + 1)];
The flaw of this approach is that in JavaScript, objects and arrays are reference types, so when we get an array, we actually get a pointer to the original array's object managed by react. If we then splice it, we already mutate the original data and whilst it does work without throwing an error, this is not really how we should do it, this can lead to unpredictable apps and is definitely a bad practice. A good practice is to create a copy of the array before manipulating it and a simple way of doing this is by calling the slice method. Slice without arguments simply copies the full array and returns a new one which is then stored. And we can now safely edit this new one and then update to react state with our new array. let me give you and example:
We have an array like this const arr=[1,2,3,4,5]. This is original array.
As I told you before, we can do that like this:
const newVar=arr.slice();
newVar.splice(Index,1);
console.log(newVar);
Or
An alternative to this approach would be to use it a ES6 feature, it is the Spread Operator
Our prior code can be something like this:
const newVar=[...arr]
newVar.splice(Index,1);
console.log(newVar);
That's it. Good luck

Define component list dynamically for Sidekick and Insert dialog in CQ5

I am trying to modify the list of components displayed in the sidekick based on the user's privileges.
I am trying it as explained here.
What i would like to know is how to send back the modified allowed array that is received as the argument, because what ever modifications i make to the array appears to be in the local scope. For e.g. if i want the allowed components to consist only of the default list component, i do something like this.
function MyHandler(cell, allowed, componentList) {
allowed = [];
allowed.push("/libs/foundation/components/list");
}
But once the control goes back to the function that triggered this event, these changes are not visible. Should i be returning the array or something ? Could you please explain if i am missing something here?
Ok. Finally figured the issue. I wanted to clear the existing list of components that were passed on to my handler, for which I used allowed = [];.
This removed all the existing references to the allowed array. (More about this explained here).
Thus changing it to allowed.length = 0; works absolutely fine.
function MyHandler(cell, allowed, componentList) {
allowed.length = 0;
allowed.push("/libs/foundation/components/list");
}

Resources