How to store array of object in react nativr async storage - react-native

I'm trying to set an array of objects in React Native AsyncStorage.
However, just the 1st item will store in it.
await AsyncStorage.setItem(
`${props.index}`,
JSON.stringify({
data: totalSet,
name: props.index,
date: today.toISOString().substring(0, 10),
})
the first item (data) is an array
Update
In my workout tracker app,
I try to create nested object. in the child component, I have following data:
weight: number
reps: number
result: also number (combination of weight and reps)
setIndex :number, which indicate the index of each sets
I have sent above data to parent component like this:
Child component
onPress={() =>
childToParent({
setDetails: [
{
setIndex: setIndex,
result: result,
weight: weight,
reps: reps,
},
],
}) + buttonStatus()
in the parent, I have given data, and trying to add into exsiting array and also adding 2 more item, date and index of each workout
parent component
const [totalSet, settotalSet] = useState([{ today }, { index }]);
useEffect(() => {
if (data != 0) {
settotalSet((current) => [...current, data]);
}
}, [data]);
then I store it into asyncstorage
const storeData = async () => {
try {
await AsyncStorage.setItem(
`${props.index}`,
JSON.stringify(totalSet)
).then((res) => console.log(res));
} catch (e) {
// saving error
}
};
and get it into another component like this
getMyObject = async () => {
try {
await AsyncStorage.getItem('1512').then((res) => {
setData(JSON.parse(res));
});
} catch (e) {
// read error
}
};
Finally as a result, I have below array:
Array [
Object {
"today": "2022-09-04",
},
Object {
"index": "1512",
},
Object {
"setDetails": Array [
Object {
"reps": "3",
"result": 13.200000000000001,
"setIndex": 0,
"weight": "12",
},
],
},
Object {
"setDetails": Array [
Object {
"reps": "3",
"result": 26.400000000000002,
"setIndex": 1,
"weight": "24",
},
],
},
]
everything is fine, except I need a nested object and this is an array.
How to create such an nested object at the first place?

Related

this.state return empty array when render

I wanted to display the array series and when I tried to console the array this.state.series in the function it does has the result and the value inside but when I render this.state.series just keep giving empty array. I wonder is it because of the componentDidMount()?
constructor(props){
super(props);
this.state={series:[]}
}
GetTransaction=()=> {
var APIURL="http://10.0.2.2:80/api/getTransaction.php";
var headers={
'Accept':'application/json',
'Content-Type':'application.json'
}
fetch(APIURL,
{
method:'POST',
headers: headers,
})
.then((response)=>response.json())
.then((response)=>
{
this.setState({results:response});
this.state.results[0].map((a) => {
this.state.series.push(a.count)
});
console.log(this.state.series)
})
.catch((error)=>
{
alert("Error"+error);
}
)
}
componentDidMount(){ // runs after the component output has been rendered to the DOM
this.GetTransaction();
}
render(){
console.log(this.state.series)
output
Array []
Array []
Array []
Array []
Array []
Array []
Array []
Array [
"1",
"2",
"1",
"1",
]
There are basically 2 errors in GetTransaction state assignment:
you can't read a state just assigned because this.setState is async. If you want to get the very last value of state you should use this.setState's callback:
this.setState({results:response}, () => {
console.log(this.state.result); //<-- here you have the very last value of result
});
state must be always setted with this.setState: this.state.series.push(a.count) is not good.
So you have to rewrite your code in this way:
...
this.setState({results:response}, () => {
let seriesAppo = [];
this.state.results[0].map((a) => {
seriesAppo.push(a.count);
});
this.setState({series: seriesAppo}, () => {
console.log(this.state.series);
})
});
...
That‘s weird
this.state.results[0].map((a) => {
this.state.series.push(a.count)
});
Don‘t manipulate state that way, only with setState.
const series = response[0];
this.setState({series: series});
Even if you wanna add elements to an array you have to recreate the array. You can achieve this as follows:
const series = response[0];
this.setState({series: […this.state.series, …series]});

How do I display specific fields from json file in a table with data?

I have around 300 records like this. Now it displays all items in the table. I want only Name,
proteins and kcal to be displayed in my table. How do I do this? I am fetching the list from an API.
[
{
"id":"711113fb-c3d1-46db-9f08-737a66ba643d",
"name":"Banana",
"fats":"0.2",
"carbohydrates":"11.8",
"proteins":"0.8",
"kcal":"46",
"tags":[
],
"tag_ids":[
],
"diet_phases":[
],
"diet_phase_ids":[
],
"product_group_id":"1cad5993-78f8-43b0-a0c5-f6f88fdf53b8",
"product_group_name":"Fruits"
},
productList: (state) => state.products.list,
This.items is an array which holds the items in my table.
mounted: this.fetchProducts().then(() => { this.items = this.productList; }); },
...mapActions ({
fetchProducts: "products/fetch",})
actions: {
fetch({ commit }) {
return api.products.list({}).then(({ data }) => {
commit(SET_LIST, data.results);
});
},
Still missing the template part of your component, and I don't know the bootstrap-vue table. So I assume your this.items just renders out each key of your item object.
So you want to controll what is rendered in the JS code and not the template, you can use the map function. So instead of directly assigning it to this.items, you can do something like this:
this.items = this.productList.map((item) => {
return {
name: item.name,
proteins: item.proteins,
kcal: item.kcal,
};
});

Filtering 2 or more categories in vue.js

I have a code where i filtered an array with a specific category.
response.data.items.filter(item => item.category_id === categ_id_1)
Now i want to add more categories in the filter (categ_id_2, categ_id_3). How do i do that?
Assuming the category_id is a primitive (ie string, number, etc), the easiest way I can think of is to maintain a Set of wanted categories and use Set.prototype.has() for filtering.
const categories = new Set(['categ_id_1', 'categ_id_2', ...])
response.data.items.filter(({ category_id }) => categories.has(category_id))
If you're wanting the list to be reactive in Vue, something like this...
data: () => ({
categoryFilters: ['categ_id_1', 'categ_id_2']
}),
computed: {
categoryFilterSet () {
return new Set(this.categoryFilters)
}
},
methods: {
async loadAndFilterData () {
const response = await axios({...}) // just guessing
const filtered = response.data.items.filter(({ category_id }) =>
this.categoryFilterSet.has(category_id))
}
}
The reason for using the computed property is that Vue does not work reactively with Set so you must back it up with an array.
Another way using Array.prototype.includes() which is used to pass/fail the test of filter for each element.
const items = [{
"a": 1,
"category_id": "categ_id_1"
}, {
"a": 2,
"category_id": "categ_id_2"
}, {
"a": 3,
"category_id": "categ_id_3"
}, {
"a": 4,
"category_id": "categ_id_4"
}, {
"a": 5,
"category_id": "categ_id_5"
}];
const search = ["categ_id_2", "categ_id_3"];
const result = items.filter(e => search.includes(e.category_id));
console.info("result::", result);
Try it as
response.data.items.filter(item => item.category_id === categ_id_1 ||item.category_id === categ_id_2 ||item.category_id === categ_id_3)

How to transform correctly data.map to Object.keys?

I had an array of data. 7 items for which I used data.map. I loaded this array on firebase and now I can't call it like this . Because this is not the Array is already in the Objects.
Question.
How do I do data.map for Objects. Moreover, I need to transfer data. Specifically: id, name , info , latlng. Inside is the ImageCard that should be in the data.map.
Example object:
Object {
"0": Object {
"id": 0,
"image": "/images/Stargate.jpg",
"info": "Stargate is a 1994 science fiction adventure film released through Metro-Goldwyn-Mayer (MGM) and Carolco Pictures..",
"latlng": Object {
"latitude": 53.6937,
"longitude": -336.1968,
},
"name": "Stargate",
"year": "1994",
},
I was advised to use Object.keys but still works incorrectly.
Since it was originally:
const url =""
then:
try {
const response = await fetch(url);
const data = await response.json();
this.setState({ data });
} catch (e) {
throw e;
}
in the render(){:
const { title, data , label } = this.state;
in the return:
{data.map(item => (
<ImageCard
data={item}
key={item.id}
onPress={() =>
navigation.navigate(IMAGEPROFILE, {
show: item,
onGoBack: this.onGoBack
})
}
/>
))}
in the ImageCard:
const ImageCard = ({ data, onPress }) => {
const { image, name, year } = data;
For the Object.keys I take data like this:
firebase
.database()
.ref("/events/" )
.once("value", data => {
if(data !== null){
this.setState({
data })
console.log(data.toJSON())
}
})
How to correct my example to transform data.map to Object.keys ?
use Object.keys and map on the returned array.
The Object.keys() method returns an array of a given object's own property names, in the same order as we get with a normal loop.
{
Object.keys(data).map(item => ( <
ImageCard data = { item } key = { item.id } onPress = {
() =>
navigation.navigate(IMAGEPROFILE, {
show: item,
onGoBack: this.onGoBack
})
}
/>
))
}

typeahead with array list in vue js

Here is my code, now i can show all the result in typeahead field. but something data are missing. How can i map all the data in one array?
data() {
return {
list: [],
}
}
axios.get('list', {})
.then(function (response) {
self.list = response.data.map(x => x.name1);
})
.catch((error) => {
console.log(error);
});
//Api return josn
[
{
"id": 17,
"name1": "Apple",
"name2": "Apple2"
},
{
"id": 237,
"name1": "Orange",
"name2": "Orange2"
}
]
now, my array is ['Apple','Oragne']
but i want my array = ['Apple','Apple2','Orange','Orange2']
There are a number of ways. You can use reduce to accumulate the array you want.
Also, your response doesn't have a data field.
Instead of:
self.list = response.data.map(x => x.name1);
Use:
self.list = response.reduce((acc, item) => {
acc.push(item.name1);
acc.push(item.name2);
return acc;
}, []);
https://jsfiddle.net/jmbldwn/h6v3mo9f/4/