Parsing through object saved in session storage - reactjs

So, I have assigned an object with two properties, the first one "items" is an array of objects saved in session storage
[{"id": 0, "name": "example"}]
the second one is just a string
"this is an example"
When I console.log postingItems it works properly and I find the object was merged
method = (e) => {
const postingItems = Object.assign({}, {
items: sessionStorage.getItem("items1"),
method: sessionStorage.getItem("method")
});
sessionStorage.setItem("items", postingItems)
console.log(postingItems)
}
but when I save postingItems in a sessionStorage and then I console.log it shows me this on the console [Object Object]
sessionStorage.setItem("finalItems", postingItems);
console.log(sessionStorage.getItem(finalItems));

You need to stringify your object first and then parse on load/get time
sessionStorage.setItem("finalItems", JSON.stringify(postingItems));
console.log(JSON.parse(sessionStorage.getItem("finalItems")));

Related

Parse content of json in React

I've a response JSON which i would like to parse. Specifically, I am interested in visualizing in an HTML the values contained in the "raw".
Below is an example of the JSON file.
{
"values":{
"first":{
"raw":"first value",
"encoded":"1019570973946118"
},
"second":{
"raw":"second value",
"encoded":"1822871964691"
}
}
}
Using JSON.stringify I can see the entire JSON but, of course that is not my intention.
Thank you
Edit:
I'm sorry, I was very superficial in my initial description. I would like to extract the value contained in raw of this example json file and display it in a react component in HTML. Something like: {JSON.stringify(raw)}
Parsing a JSON string to an actual javascript object is NOT done by JSON.stringify() but by JSON.parse().
So in order to retrieve the raw part you would have to do this:
const response = `{
"values":{
"first":{
"raw":"first value",
"encoded":"1019570973946118"
},
"second":{
"raw":"second value",
"encoded":"1822871964691"
}
}
}`;
const parsedJSON = JSON.parse(response)
for (const key of parsedJSON.values.keys()) {
const raw = parsedJSON.values[key].raw;
console.log(raw)
}
The variable raw could be used as a prop, state, etc. now.

Why is Array.push() throwing an error but Array.concat() does not?

I am trying to add an array to an existing array. The initial data is like this:
props: {
ItemData: // This prop gets populated with data from the parent component. That data comes from a Vuex store.
{
type: Array,
default: null
}
}
setup(props) {
const Item = ref(props.ItemData);
onMounted( ()=> {
Form.Title = Item[0].Title
Form.Files = Item[0].Files
}
)
}
Which results in something like this:
Form = reactive({
Title: null,
Files: [
{name: "photo", extension: ".webp" size: '1024'},
{name: "doc", extension: ".pdf" size: '2048'}
]
)}
The data in Form.Files comes from a prop that is sent to this component from Vuex data:
Form.Files may also be an empty array [ ] if there are no existing files when the form is loaded.
When the user adds new files, the data for the new files is like this:
NewFiles = [
[
File,
{name: "newphoto", extension: ".jpg", size: "1024" }
],
[
File,
{name: "newdoc", extension: ".docx", size: "2048" }
]
]
File is the file object itself as selected via an input field e.g. <input multiple type="file" />
So how do we add NewFiles to Form.Files? I tried the following:
Form.Files.push(...NewFiles);
That somewhat works in that the Vue debugger shows the NewFiles array added to Form.Files, but it thrown an error of [vuex] do not mutate vuex store state outside mutation handlers. and the rest of the code fails.
So I tried concat() which works:
const AllFiles = Form.Files.concat(NewFiles);
Form.BroadcastFiles = AllFiles;
There's no errors but I don't understand why push() would cause a Vuex error when I'm not touching any Vuex state, and even if I was, why doesn't the contact() cause the same error?
.concat returns a new array with both the current items and the new ones where .push modifies the current array instead of returning a new one.
If that array was initially loaded from vuex it results in an unwanted mutation of the store.
Edit:
In the store
mutations: {
addFile(state, file) {
state.ItemData[0].Files.push(file);
},
}
In the component
NewFiles.forEach(file => store.commit("addFile", file));
I suggest you check this article about the use of spread operator in Javascript, and array reference How to Use the Spread Operator (…) in JavaScript especially the "A note about copying by reference" section. So basically you are mutating the state of Form.Files while using concat and you are losing the reference using the spread operator. One solution can be:
let AllFiles = [...Form.Files];
AllFiles.concat(NewFiles);
Form.BroadcastFiles = AllFiles;

Object Promise is returned when accessing specific object attribute in an array of objects? (Angular - Ionic)

I have an array of objects, I want to be able to mention a specific attribute within a single object within that array. What I have done so far is as follows:
I am storing my array of objects within Ionics storage. I then use an async function to assign the array of objects to an array in my typescript file: This can be seen here;
//The new array
users: User[] = [];
//The async function
async readUsers() {
this.users = await this.service.readUsers();
this.index = this.users.findIndex((x => x.id == this.passed_id));
return this.users[this.index];
}
The async function assigns the array to this.users, after which I then find the object i want and assign its index to this.index, which i then use to identify the desired object in the this.users array. Everything up until here works just fine, i manage to get the desired object within the stored array.
I am then able to read the attributes of the selected object using:
"alert(this.users[this.index].firstName)", instead of the last line in the async function. This works fine as well.
However, now i want to mention a specific object in a form builder control as follows:
firstName: [this.readUsers(), Validators.required],
This does not work, and all that is returned is [Object Promise]. What am i able to do here in order to read a specific attribute (as text) in the form input from the object array mentioned above? Any help is appreciated.
You have to await this.readUsers() for the unwrapped value.
async method() {
...
firstName: [await this.readUsers(), Validators.required],
...
}
Maybe for you, you have to do something like this:
form: any; // using any, but you can change the type to what FormBuilder returns
....
async ngOnInit() {
const users = await this.readusers();
this.form = this.formBuilder.group({
firstName: [users, Validators.required],
});
}

How to push array of objects into state using hooks

I have a useState as const [responses, setResponses] = useState([]);
I get the response and log it as follows :
const tempResults = res.data.data;
console.log(tempResults.length);
console.log(tempResults);
The log shows as:
When I click to open the Array of 6 items, results are .
So it is an array of objects.
I tried to set the initial value of the state as per the object
{
"index": 0,
"ds": "2020-03-06",
"yhat_lower": -10712.5597359237,
"yhat_upper": 25376.4649581317,
"yhat": 6955.3671910982,
"mape": 21.4472070205,
"rmse": 667.0969808414,
"mae": 475.3343871057,
"smape": 5.143548286
}
But when I logged, the state only had the initial value and had not appended the response array.
I am setting state as :
setResponses(...responses, tempResults);
const x = typeof responses;
console.log("TypeOfResponse", x);
console.log("RESPONSES ", responses);
However, the state of the 'responses' object as per console is this:
So it is not able to save the Array object into state. What could be wrong? Any suggestions, please?
if res.data.data is an array
then set to setResponses like this
setResponses(res.data.data)
or
setResponses([...responses, ...res.data.data])

Tried to get frame for out of range index NaN (realtime database)

I'm trying to render some rows from firebase database, I'm getting this error:
TaskQueue: Error with task : Invariant Violation: Tried to get frame
for out of range index NaN
const { currentUser } = firebase.auth();
var userfavorites = firebase.database().ref(`/users/${currentUser.uid}/favorites/`);
userfavorites.once('value').then(snapshot => {
this.setState({ userfav: snapshot.val() })
})
...
<FlatList
data={this.state.userfav}
renderItem={({ item }) => (
<Text>{item.favdata}</Text>
)}
/>
I came across this error, I had a PHP back-end and trying to get json_encoded data into a FlatList.
Problem: The REST endpoint was returning an object eg
{"Total_Excavator":2,"Active_Excavator":2,"Total_load":6804}
Solution: Fixed it to return an array rather eg
[{"Total_Excavator":2,"Active_Excavator":2,"Total_load":6804}]
Take note of the Square Brackets.
I used $data[] = json_encode($excavatorArray) instead of
$data = json_encode($excavatorArray)
. Hope it helps someone one day
I had the same issue, it seems this problem is the reason of the object names.
In the image below you can see that as soon as you fetch snapshot from Firebase endpoint it comes with the id which is not recognized by React Native. And react acts like it's empty obj.
All you have to do is map the items of the object after fetching it like example below,
const fbObject = snap.val();
const newArr = [];
Object.keys(fbObject).map( (key,index)=>{
console.log(key);
console.log("||");
console.log(index);
newArr.push(fbObject[key]);
});
Just a slight modification to the answer from #mert. JavaScript's map operator returns an array; so, there is no need to push elements onto newArr. Also, the new array's elements are going to be missing the unique Firebase id. So, it should be added into the array element.
const fbObject = snapshot.val();
const newArr = Object.keys(fbObject).map((key) => {
fbObject[key].id = key;
return fbObject[key];
});
You'll end up with a newArray like this:
[
{
"id": "12345",
"name": "Jane Doe",
"age": 18
},
{
"id": "23456",
"name": "John Smith",
"age": 27
}
]
I had a similar problem and saved the flatlist's data in the state. You have to make sure that the data in the state is a list instead of an object:
this.state = {
...,
data: [], // <-- wrap your flatlist's data in there
}
When making changes to your data/the state, always use the callback function to perform something afterwards to keep your UI in sync:
this.setState({..., data}, () => yourCallback())

Resources