How to create the sectiondata in the react native sectionlist - reactjs

I want show the data from my API use Sectionlist in the react native
but I have no idea how to generate the sectionData.
I think my data is too complex to understand and let me confuse.
The struct like below
"Info": [
{
"Name": "test1",
"Data": [
{
"sss": "1215",
"aaa": "1010133000001",
},
{
"sss": "1215",
"aaa": "1010133000001",
}
]
},
{
"Name": "test2",
"Data": [
{
"sss": "1215",
"aaa": "1010133000001",
},
{
"sss": "1215",
"aaa": "1010133000001",
}
]
}
]
}
I want show the SectionHeader use Nameand show the Contents use Data.
Now I can get data use potion of code like below. How can I go on? Thank you!
for (let idx in jsonData) {
let Item = jsonData[idx];
console.log(Item.Name)
for (let index in Item.Data) {
Item2 = Item.Data[index];
console.log(Item2.sss)
}
}

First, you have to update your data array,
let newArray = []
for (let item in jsonData) {
let dict = {
title: item.Name,
data: item.Data
}
newArray.push(dict)
}
After the above code, you will get the array for section list.
Then use this like the following,
...
<SectionList
renderItem={({item, index, section}) => <Text key={index}>{item.sss}</Text>}
renderSectionHeader={({section: {title}}) => (
<Text style={{fontWeight: 'bold'}}>{title}</Text>
)}
sections={this.state.data}
keyExtractor={(item, index) => item + index}
/>
...
The 'this.state.data' is your new array.
And renderItem is used for rendering section data
And renderSectionHeader is used for rendering section header.

provide an array of items, this will spit out the section data
// maps it's an array of objects
// groupBy to extract section headers
let dataSource = _.groupBy(maps, o => o.name);
// reduce to generate new array
dataSource = _.reduce(dataSource, (acc, next, index) => {
acc.push({
key: index,
data: next
});
return acc;
}, []);
return dataSource;

Related

How to use condition with Vuejs with array and v-for?

I have an array file load with Axios, the problem is in this have an array that has image and video and I can't change it, I want to just the array that has only image, can someone please help to do that, thank you~
{
"data": [
{
"id": "01",
"media_type": "IMAGE",
"media_url": "https://...",
},
{
"id": "02",
"media_type": "VIDEO",
"media_url": "https://...",
},
{
"id": "02",
"media_type": "IMAGE",
"media_url": "https://...",
},
...
]
}
<div class="xx" v-for="event in events.data.slice(0, 6)" v-if="event.media_type == 'IMAGE'">
<img :src="event.media_url" :alt="event.caption">
</div>
data() {
return {
insta: "gram",
events: []
}
},
created() {
axios
.get('https:...')
.then(response => {
this.events = response.data
})
.catch(error => {
console.log('There is an error: ' + error.response)
})
},
You shouldn't really be mixing v-for and v-if directives, because they are confusing, officially discouraged both in Vue2 and Vue3, and most importantly, they have different precedence in Vue2 vs Vue3.
If you want to work off a filtered array (in this case, you want images only), then create a computed prop that is based off the original data. From your code it is not clear if you want to perform which operation first:
Getting the first 6 entries
Getting only images
Let's say you want to get all images, and then return the first 6 images, then this will work:
computed: {
filteredEvents() {
return this.events.data.filter(d => d.media_type === 'IMAGE').slice(0,6);
}
}
If you want to get any 6 first entries and then filter them by image, then simply switch the chaining around:
computed: {
filteredEvents() {
return this.events.data.slice(0,6).filter(d => d.media_type === 'IMAGE');
}
}
Then you can use this in your template:
<div class="xx" v-for="event in filteredEvents">
<img :src="event.media_url" :alt="event.caption">
</div>

How can I use .map on an array to create a new JSON object for each item?

how can I use map on an array to map each item to a new JSON structure?
For example my original array looks like this:
result= [
{
"pageIndex":1,
"pageName":"home",
"cssConfiguration":"fa fa-home"
}, ...]
And I want to use .map to create a different structure for the JSON objects, for example:
modifiedResult = [
{
"id":1,
"name":"Home"
},...]
I've tried to do something like this:
result.map((resultItem) => { name: resultItem["pageName"], id:resultItem["pageIndex"]});
But it doesn't work :(
In your approach are missing the parentheses within the handler:
result.map((resultItem) => { name: resultItem["pageName"], id:resultItem["pageIndex"]});
^
You can use the function map and destructuring-assignment as follow:
let arr = [ { "pageIndex":1, "pageName":"home", "cssConfiguration":"fa fa-home" }],
result = arr.map(({pageIndex: id, pageName: name}) => ({id, name}));
console.log(result)
You can use map:
const result = arr.map(({pageIndex, pageName}) => ({id: pageIndex, name: pageName}))
An example:
let arr = [
{
"pageIndex":1,
"pageName":"home",
"cssConfiguration":"fa fa-home"
}]
const result = arr.map(({pageIndex, pageName}) => ({id: pageIndex, name: pageName}))
console.log(result)

array with objects containing array

Sorry guys if my way of asking the question in the title is not correct.
I am working on a project on react js and I am getting the data like this
[
{
"count": [
{
"1": 16
},
{
"1": 149
}
],
"day": "2019-08-27"
}
]
now this is my first time I am dealing with this kind of data and I really have no idea how can I show it like this I am really sorry guys I literally can't even show what I have tried because it does not seem relevant
[
{
count: 165
day:"2019-08-27"
}
}
Assuming the data you're getting is under a variable called data you could use reduce:
The below makes the assumption the count is always an array of objects with just 1 key called '1'.
const newData = data.map(datum => {
datum.count = datum.count.reduce((count, item) => {
return count + item['1']
}, 0)
return datum
})
You can try something like this:
let arr = [
// item
{
count: [
{
"1": 16
},
{
"1": 149
}
],
day: "2019-08-27"
}
];
arr.map(item => {
Object.keys(item).map(key => {
console.log(item[key])
// if item[key] is iterable
if(Array.isArray(item[key])) {
item[key].map(val => {
console.log(item)
})
} else {
console.log(item[key])
}
});
});
The concept is that for Objects you do a Object.keys().something and for an array you do a arr.map(item => ...)

Is there any way to update state by find Item and replace on a nested state?

I am building an order functionality of my modules in the component state on react
so the state object looks like that
"activity": {
"name": "rewwerwer",
"description": "werwerwerwerwer",
"modules": [
{
"name": "Text",
"order": 1,
"module_id": 1612,
},
{
"name": "Text2",
"order" 2,
"module_id": 1592,
}
]
}
handleSortUp = (moduleid ,newOrder) => {
const { modules } = this.state.activity;
const module = modules.find(element => element.module_id === moduleid);//Thios returns the correct object
this.setState({ activity: { ...this.state.activity.modules.find(element => element.module_id === moduleid), order: newOrder } });
}
I tried this but it updates the order field and object
but also removes all other objects from modules array :<
I like just to replace only the order field on each module by module id
and leave rest data there
the required response from the state that i need when the handleSortUp(1612,14); is fired
handleSortUp(1612,2);
{
"name": "rewwerwer",
"description": "werwerwerwerwer",
"modules": [
{
"name": "Text",
"order": 2,
"module_id": 1612,
},
{
"name": "Text2",
"order": 1,
"module_id": 1592,
}
]
}
I can do this on a simple array the question is how to update the State on react
Also the one way to change the order is answered fine but how also to change the field that had that order registered
So when we fire Change Item 1 order to 2 the Item 2 needs to take the Order 1
Thank you
Sure! This would be a great place to use the built-in .map method available for arrays. Consider the following example.
let array = [{order: 1, type: "food"}, {order: 2, type: "notfood"} ]
const newArray = array.map((item) => {
//CHECK TO SEE IF THIS IS THE ITEM WE WANT TO UPDATE
if(item.order == 1){
return {
...item,
newField: "newData"
}
} else {
return item
}
})
Output is:
[{order: 1, type: "food", newField: "newData"}
{order: 2, type: "notfood"}]
So yes you could totally update the module you're looking for without mutating the rest of your array. Then use your findings to update the component state using some good ol spread.
this.setState({
activity: {
...this.state.activity,
modules: newArray}
})
Of course they get all eliminated. Pay attention to what you wrote here:
this.setState({ activity: { ...this.state.activity.modules.find(element => element.module_id === moduleid), order: newOrder } });
What are you doing with that find? Let's see what Array.prototype.find() returns: https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Array/find
It returns an index, why would you insert an index into the state?
The answer partially came from yourfavoritedev.
As he said you can use the built-in Array.prototype.map() and do it like this:
handleSortUp = (moduleid ,newOrder) => {
const { modules } = this.state.activity;
const newModules = modules.map(module => module.module_id === moduleid ? { ...module, order: newOrder } : module)
this.setState({ activity: { ...this.state.activity, modules: newModules } });
}
This should work, let me know but I strongly advice to ask me or search on the web if you don't understand what is happening there (syntactically or semantically speaking).

How do you access all values in JSON array?

The only data I can access right now is the beginning part of the array:
[
{
/*start*/
"username" : "Bob",
"password":"123456",
"bio":"Hi",
/*End*/
"data":
[
{
"pet" : "dog",
"age" : "20",
"city" : "5"
},
{
"pet" : "cat",
"age" : "18",
"city" : "7"
}
]
}
]
I can also access part of the data array, but I am trying to access all of it. For example: {item.data[1].pet}. I tried using a for loop but was unsuccessful with that. I am also using react-native flat list and doing dataSource: responseJSON.data didn't work for me either. I'm sure there has to be a way to access all of the values of petinstead of just one each time, I just don't know how to.
Also since I am a beginner any tips will be gladly appreciated.
EDIT: Attempts at trying to loop from outside the JSX:
var itemList = [];
for (var i = 0; i < responseJSON[0].data.length; i++) { itemList.push(<Text> {responseJson[0].data[i].pet}</Text>); }
I put that out of the render() Then I take itemList and stick it here:
<FlatList
data={ this.state.dataSource}
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem={({item}) => <View>
{itemList}
</View>
}
keyExtractor={(item, index) => index}
/>
Now it's not understanding that itemList is a variable. I'm getting a syntax error.
EDIT 2: Thanks to everyone the only thing I need help with is putting a variable inside of componentDidMountin React Native.
I have no experience with React but from what I've found it seems it should be done this way:
const responseJson = [
{
/*start*/
"username" : "Bob",
"password":"123456",
"bio":"Hi",
/*End*/
"data":
[
{
"pet" : "dog",
"age" : "20",
"city" : "5"
},
{
"pet" : "cat",
"age" : "18",
"city" : "7"
}
]
}
];
const listItems = responseJson[0].data.map((details) =>
<li>{details.pet}</li>
);
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('root')
);
The output I get is:
dog
cat
You can do it like this in javascript:
var json = {"data":[{"pet":"dog","age":"20","city":"5"},{"pet":"cat","age":"18","city":"7"}]};
for (var i = 0; i < json.data.length; i++) {
var object = json.data[i];
console.log(object);
console.log(object.pet, object.age, object.city);
}
Try this loop :
for (var i = 0; i < responseJSON[0].data.length; i++) {
alert(responseJSON[0].data[i].pet);
}
Working example here :
https://plnkr.co/edit/c1sZYKrBWHFJOKwHEMbU?p=preview
Why don't you convert all the data in the responseJson to objects using Lodash Library and then take the data object from it and assign it to a variable and then convert it back to an array. And after that you change the data source to that array you get
See the Documentation of Lodash here

Resources