I have a FaltList component that looks like this:
<FlatList>
data = {this.state.array}
...
renderItem={({ item }) => (
<View>
<Text>hello, {item.item.name}</Text>
</View>
)}
...
</FlatList>
this.state.array looks like this:
Array [
Object {
"//user1": Object {
"id": "//user1",
"name": "Peter",
},
"//user2": Object {
"id": "//user2",
"name": "Tim",
},
},
]
I get an error which says:
TypeError: undefined is not an object (evaluating 'item.item.name')
do you know how to fix it? Thank you!!
Related
App.js
I am facing this issue file error - Uncaught TypeError: items.data.map is not a function. I have tried some other options but did not work. I cant seem to find what I am doing wrong.
.then((res) => res.json())
.then((json) => {
this.setState({
items: json,
DataisLoaded: true
});
})
}
render() {
const { DataisLoaded, items } = this.state;
if (!DataisLoaded) return <div>
<h1> Loading data ... </h1> </div> ;
return (
<div className = "App">
<h1> Fetch data from an api in react </h1> {
items.data.map((item) => (
<ol key = { item.data} >
Continents: {item.data[0]}
</ol>
))
}
</div>
);
}
}
export default App;
JSON Data
Nested API data from json data type.
{
"data": {
"data": [
{
"project_id": "xxxx",
"title": "xxx34",
"description": "xxx23",
"expense": 1699126,
"budget": 6418516,
"country": "xxx",
"sector": [
{
"name": "Accelerate structural transformations",
"code": "18"
}
],
"sdg": [
{
"name": "Peace, justice, and strong institutions",
"id": "16"
}
],
"signature_solution": [
{
"name": "Strengthen effective, inclusive and accountable governance",
"id": "2"
}
],
"donor": [
"Australian DFAT",
"GLOBAL FUND TO FIGHT AIDS, TUBERCULOSIS",
"UNITED NATIONS DEVELOPMENT PRO"
],
"marker": [
"Hows",
"Joint Programme",
"Partner",
"Whos",
"COVID-19 Response"
]
},
{
],
"links": {
"next": null,
"previous": null
},
"count": 44
},
"status": 200,
"success": true
}
I tried data.data.map but still facing the same error. What am I doing wrong here?
Firstly, the TypeError you got is syntax error. The implementation of an arrow function must follow by curly brackets
items.data.map((item) => (
<ol key = { item.data} >
Continents: {item.data[0]}
</ol>
))
to
items.data.map((item) => {
<ol key = { item.data} >
Continents: {item.data[0]}
</ol>
})
Secondly, items you are mapping is a nest of JSON object - key: value pair. It's not suitable for mapping.
The mapping iterator or iterating an array is perfect when used to retrieve
data from a sequence item have the same or similar structure.
E.g:
const arr = [{"id": "1", "name": "a"}, {"id": "2", "name": "b"}, {"id": "3", "name": "c"}];
arr.map((item) => {
console.log(item.id);
console.log(item.name);
})
You should pretreat your data first.
as the title suggests I would like to know how to use the getParam function to access a nested array. This is my json and my code.
Json:
[
{
"name": "Crock Pot Roast",
"ingredients": [
{
"quantity": "1",
"name": " beef roast",
"type": "Meat"
},
{
"quantity": "1 package",
"name": "brown gravy mix",
"type": "Baking"
},
{
"quantity": "1 package",
"name": "dried Italian salad dressing mix",
"type": "Condiments"
},
{
"quantity": "1 package",
"name": "dry ranch dressing mix",
"type": "Condiments"
},
{
"quantity": "1/2 cup",
"name": "water",
"type": "Drinks"
}
],
"steps": [
"Place beef roast in crock pot.",
"Mix the dried mixes together in a bowl and sprinkle over the roast.",
"Pour the water around the roast.",
"Cook on low for 7-9 hours."
],
I capture the data that interest me and print them, accessing the nested array via map (quantity values, name, type) in this screen.
Screen1:
<FlatList
numColumns={2}
data={this.state.breweries}
renderItem={({ item, index }) => (
<View style={styleResult.box}>
<TouchableOpacity onPress={() =>this.props.navigation.navigate('ReviewDetails', item)}>
<Image style={styleResult.logo}
source={{uri: item.imageURL}} />
<Text style={styleResult.titleRecipe}> {item.name}</Text>
{item.ingredients.map((v,i) => (
<Text style={styleResult.titleRecipe}> {v.name}</Text>
))}
</TouchableOpacity>
But when I want to bring every single value to a second page via onpress, in screen 2 if I want to print the name I can with getParam ('name'), but if I wanted to print the names of the ingredients, I don't know how to do it.
Screen2
const link=navigation.getParam('imageURL');
return(
<View style={styleReviewDetails.container}>
<ScrollView>
<Text style={styleReviewDetails.titleRecipe} >{navigation.getParam('name')}</Text>
<Image style={styleReviewDetails.imageRecipe} source={{uri: link}}></Image>
<Text style={styleReviewDetails.titleRecipe} >Ingredients: ???????</Text>
In your details screen you have an object of the json type you posted.
Therefore, if you want to have a string which contains the ingredient names you could obtain it like this:
const ingredients = navigation.getParam('ingredients') // here you have the list
const ingredientNames = ingredients.map((ingredient) => ingredient.name)
// if you want to put there a separator, like "," you can do it like this:
const ingredientNames = ingredients.map((ingredient, index) => `${ingredient.type}` + ( index !== ingredients.length-1 ? " ," : ""))
// in your code it will be used like this
...
<Text>
{ingredientNames}
</Text>
I get an array after console log my state that get data from Firebase. I want to know: can anyone help me to map array and get below details on ui. Thank You.
I tried below way, but app keep getting errors
Array [
Object {
"lists": Array [
Object {
"lists": Array [
Object {
"id": "123",
"imageUrl": "http://www.pngmart.com/files/1/Pizza-Slice-PNG-Transparent-Image.png",
"name": "Chicken Devill pizza",
"price": 700,
"size": "Medium",
},
],
"randomid": "32013408-0f48-4b15-80c4-eba3fc1fe295",
},
Object {
"lists": Array [
Object {
"id": "1234",
"imageUrl": "http://www.pngmart.com/files/1/Cheese-Pizza.png",
"name": "Cheese pork pizza",
"price": 1500,
"size": "Medium",
},
],
"randomid": "12a74805-4932-4397-b838-6773bc7e44b8",
},
],
},
]
In below code it show a error:
TypeError: undefined is not a function (near '...this.state.lists.map...')
{this.state.lists.lists.map((current, i) => (
))}
The first list here is an array not an Object. You can't call lists.lists because of this.
You will need to flatten the list or use nested map operations.
export default function App() {
const state = {
lists: [
{
lists: [
{
id: "123",
imageUrl:
"http://www.pngmart.com/files/1/Pizza-Slice-PNG-Transparent-Image.png",
name: "Chicken Devill pizza",
price: 700,
size: "Medium"
}
],
randomid: "32013408-0f48-4b15-80c4-eba3fc1fe295"
},
{
lists: [
{
id: "1234",
imageUrl: "http://www.pngmart.com/files/1/Cheese-Pizza.png",
name: "Cheese pork pizza",
price: 1500,
size: "Medium"
}
],
randomid: "12a74805-4932-4397-b838-6773bc7e44b8"
}
]
};
return (
<div className="App">
{state.lists.map((list) => {
return list.lists.map((item) => {
return <p>{item.id}</p>;
});
})}
</div>
);
}
You can find this working here: https://codesandbox.io/s/nervous-tu-u2h8v?file=/src/App.js
I also want to add some thing by myself
I done the mapping inside a mapping like this
{this.state.lists.map((current, i) => (
<View>
{current.map((current, i) => (
<Fragment>
<TouchableOpacity style={styles.card} onPress={() => this.details(current.id)}>
<Image style={styles.img} key={i} source={{uri: current.lists[0].imageUrl}}/>
<Text style={styles.txt} key={i}>{current.lists[0].name}</Text>
<Text style={styles.txt} key={i}>{current.lists[0].size}</Text>
<Text style={styles.txt} key={i}>LKR.{current.lists[0].price}</Text>
</TouchableOpacity>
</Fragment>
))}
</View>
))}
I have fetched some data from an API as a JSON array in componentDidMount method as below.
componentDidMount() {
return fetch('http://..someAPI../product/')
.then(res => res.json())
.then(resJson => {
this.setState({
isLoading: false,
dataSource: resJson,
});
var objects = this.state.dataSource;
for (var i = 0; i < objects.length; i++) {
console.log('Item Name: ' + objects[i].productName);
}
})
.catch(err => {
console.log(err);
});
}
In here I get console.log output as I want. Now I want to pass the array in a loop as a prop to a custom component, but it gives error.
My render method looks like this
return (
<View>
<Content>
{this.state.dataSource.map(item => {
<Product Name={item.productName} price={item.price}/>;
})}
</Content>
</View>
);
My original Json object looks like this
[
{
"category": [
"Food",
"Bread",
"Bun"
],
"_id": "1",
"productName": "Sausage bun",
"price": 70,
"details": "test product",
},
{
"category": [
"Food",
"Bread",
"Bun"
],
"_id": "2",
"productName": "Fish Pastry",
"price": 50,
"details": "test product",
}
]
I want to pass these data to display the products as a loop. How can I do this? Thank you in advance!
Since data loading is asynchronous you probably have uninitialised state.
As a safer coding practice you could something like
{this.state.dataSource && this.state.dataSource.map(item => {
return <Product Name={item.productName} price={item.price}/>;
})}
Depending on your webpack configuration , you can also use optional chaining https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
{this.state?.dataSource?.map(item => {
<Product Name={item.productName} price={item.price}/>;
})}
Also,
initialize your state
this.state = {
dataSource: []
}
I have an array:
[
{
"room": {
"id": "1",
"name": "NameRoom"
},
"users": [
{
"userId": "1",
"userName": "User1",
},
{
"userId": "2",
"userName": "User12",
},
{
"userId": "3",
"userName": "User13",
}
]
},
{
"room": {
"id": "2",
"name": "NameRoom2"
},
"users": [
{
"userId": "4",
"userName": "User14",
},
{
"userId": "5",
"userName": "User15",
},
{
"userId": "6",
"userName": "User16",
}
]
},
]
Here is my rendering code
componentDidMount() {
fetch('https://site.ru/api/rooms')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
dataSource: responseJson,
})
console.log(responseJson[0].users[0].userName) // i get User1
})
.catch((error) => {
console.log(error)
})
}
renderItemRooms = ({ item,index }) => (
<View style = {styles.containerHeader}>
<Text style = {styles.dateTitle}>16.04.2020</Text>
</View>
<TouchableOpacity style = {styles.containerMain}>
<Text style = {styles.nameTitle}>RoomName</Text>
<IconButton
style={styles.menuIcon}
icon="text"
color={'#e7eee6'}
size={40}
onPress={this._toggleBottomNavigationView}
/>
<BottomSheet
visible={this.state.visible}
onBackButtonPress={this._toggleBottomNavigationView}
onBackdropPress={this._toggleBottomNavigationView}
>
<View style={styles.bottomNavigationView}>
<View style={styles.bottomList}>
<FlatList
keyExtractor={item => item.name}
data={this.state.dataSource}
renderItem={this.renderItemUsers}
/>
</View>
<View style={styles.bottomButton}>
<TouchableOpacity style={styles.buttonStyle}>
<Text>Connect</Text>
</TouchableOpacity>
</View>
</View>
</BottomSheet>
</TouchableOpacity>
)
How can I display a list of users in the internal render in my code?
And print the names of rooms.
How to iterate through such an array correctly?
I need to output TouchableOpacity with the name of the room, it has a button on the right, when you click it, a modal menu appears, which contains a list of users in this room, how do I do this correctly?
I've already searched the Internet and didn't find a similar problem.
I notice that you have missed something in FlatList, also there many methods to iterate an array. I will give you an example here and hope this helps.
Example:
<FlatList
keyExtractor={item => item.room.name} {/* item.name is undefined, you need to add room.name */}
data={this.state.dataSource}
renderItem={this.renderItemUsers}
/>
// And renderItemUsers method
renderItemUsers = ({ item }) => {
const Users = () => item.users.map(user => <Text key={user.userId}>{user.userName}</Text>)
return (
<View>
<Text>Room : {item.room.name}</Text>
<Users />
</View>
)
}