I can't render my data from the DB with a .map - javascript

I'm currently working on a react native app, and I have an issue about render information (in an array) that I fetch from my DB. To do that I have to write a .map.
I receive the data from the fetch in the console.log.
When I call my function with this "()".
<Text>Choisissez votre Choix Club </Text>
<TouchableOpacity>
<View>
<Text>{this.renderMesClubs()}</Text>
</View>
</TouchableOpacity>
An error message appear
TypeError: undefined is not an object (evaluating '_this.state.sport.club.map')
Below you can find the all code page.
class ChoixClub extends Component {
constructor(props) {
super(props);
this.state = {
sport: {club: []},
};
}
getMesClubs = () => {
const headers = new Headers({'Content-type': 'application/json'});
const options = {
method: 'GET',
headers: headers,
};
fetch('http://localhost:8080/inscription/sport', options)
.then((response) => {
return response.json();
})
.then(
(data) => {
const club = JSON.stringify(data);
this.setState({sport: club});
console.log(this.state.sport.club);
},
(err) => {
console.log(err);
},
);
};
renderMesClubs = () => {
return this.state.sport.club.map((element) => {
return (
(
<View className="articles">
<Text>{element.nomClub}</Text>
</View>
),
console.log(element.nomClub)
);
});
};
componentDidMount() {
this.getMesClubs();
}
render() {
return (
<SafeAreaView>
<Text>Choisissez votre Choix Club </Text>
<TouchableOpacity>
<View>
<Text>{this.renderMesClubs()}</Text>
</View>
</TouchableOpacity>
<Text>Choisissez votre rival</Text>
<TouchableOpacity></TouchableOpacity>
</SafeAreaView>
);
}
}
export default ChoixClub;
I hope my message is clear enough for you to solve it, and thanks in advance for your answer!

You are calling JSON.stringify(data), which turns "data" into a string. assuming that the server is returning valid JSON, then calling response.json(), which you are already doing, should give you a Javascript object, hopefully an array, you should map over that, not turn it back into a string and map over the string.
to check if data really is an array you can use:
if(!Array.isArray(data)){
throw new Error('expected the response to be an array');
}

All your data is actually contained by an array, so you need to specify the element or iterate it. As #user1852503 said, no JSON.stringify is needed because .then((response) => { return response.json(); }) does the trick
// Let's your data
let data = [ { "_id": "5f44dcc0a3da3a3008a71e5d", "sport": { "_id": "5f44dcc0a3da3a3008a71e5e", "club": [ { "_id": "5f44dcc0a3da3a3008a71e5f", "nomClub": "String", "classement": "String", "dateMatch": "String", "classementDB": "String" } ] }, "__v": 0 } ];
data[0].sport.club.map(element => {
// I just console log it to see if it works
console.log(element.nomClub)
})

Related

React Native Spotify api getting a users playlist

Hi I'm currently working on a react native app and I'm trying to get a users playlist and then return it in a flatlist. I've completed getting a users access_token but I'm a little stuck on figuring out how to actually use the data. I'm fairly new to using api data.
export default function SpotifyGetPlaylist(props) {
const { colors } = useTheme();
const [token, setToken] = useState('');
const [data, setData] = useState({});
React.useEffect(() => {
getData();
}, []);
const getData = async() => {
setToken (await AsyncStorage.getItem('#access_token'));
console.log("token retrieved")
}
const handleGetPlaylists = () => {
axios.get("https://api.spotify.com/v1/me/playlists", {
headers: {
Authorization: `Bearer ${token}`,
},
}).then(response => {
setData(response.data);
console.log(response.data)
})
.catch((error) => {
console.log(error);
});
};
}
This part works fine and returns data into the console as such
Object {
"collaborative": false,
"description" : "Maailman – Päivittäinen katsaus siihen, mitä kappaleita kuunnellaan eniten juuri nyt.",
"external_urls": Object {
"spotify": "https://open.spotify.com/playlist/37i9dQZEVXbMDoHDwVN2tF",
},
"href" : "https://api.spotify.com/v1/playlists/37i9dQZEVXbMDoHDwVN2tF",
"id" : "37i9dQZEVXbMDoHDwVN2tF",
"images": Array [
Object {
"height": null,
"url" : "https://charts-images.scdn.co/assets/locale_en/regional/daily/region_global_large.jpg",
"width" : null,
},
],
"name": "Maailman – Top 50",
"owner": Object {
"display_name" : "Spotify",
"external_urls": Object {
"spotify": "https://open.spotify.com/user/spotify",
},
"href": "https://api.spotify.com/v1/users/spotify",
"id" : "spotify",
"type": "user",
"uri" : "spotify:user:spotify",
},
"primary_color": null,
"public" : true,
"snapshot_id" : "NzAzNDIxMzk0LDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDY2Njk=",
"tracks": Object {
"href" : "https://api.spotify.com/v1/playlists/37i9dQZEVXbMDoHDwVN2tF/tracks",
"total": 50,
},
"type": "playlist",
"uri" : "spotify:playlist:37i9dQZEVXbMDoHDwVN2tF",
},
But I'm having problems actually rendering anything into the Flatlist which at the moment looks like this.
const renderItem = ({item}) => {
<Item title={item.name}/>
}
return (
<View style={styles.container}>
<Button
onPress = {handleGetPlaylists}
color = "#1DB954"
style = {{ color: colors.text, width: 100 }}
title = "Get your playlists"/>
<FlatList
data = {data}
renderItem = {renderItem}
keyExtractor= {(item) => item.id.toString()}
/>
</View>
)
I'm unsure how I get the data from the api my hunch is that I would have to use data.items.name to access it but it doesnt work for me. Help is much appreciated
Nothing is appearing in the FlatList render because you're not returning your Item. Because you have curly braces around the body of the function, you have to explicitly return the component.
const renderItem = ({item}) => {
return <Item title={item.name} />;
}

Function doesn't return Object but undefined instead

I want to return and object that I create in a Firestore call to my UI component.
Upon a lot of research regarding using async functions and .then() to receive data from a function, I still cannot get it to work.
I just get undefined.
Most answers I have found say that I should use await and/or .then() when handling the response so not to just get a promise. But nothing I have tried gets some actual data. The object is always undefined.
Firebase config:
export const getLatestAcceptedSample = async (bottleID, equipmentID) => {
let msg = {}
try {
await db.collection('Oil Samples').orderBy('createdAt', 'desc').limit(1).get().then(querySnapshot => {
querySnapshot.forEach(documentSnapshot => {
const tempMsg = documentSnapshot.data()
if (bottleID === tempMsg.bottleID && equipmentID === tempMsg.equipmentID) {
msg = {
bottleID: tempMsg.bottleID,
equipmentID: tempMsg.equipmentID,
timestamp: tempMsg.createdAt?.toDate() ?? '',
userName: tempMsg.authorName,
userID: tempMsg.authorID,
title: tempMsg.title
}
console.log(msg)
return msg
} else {
alert("Fetching data from database failed")
}
return msg
})
})
}
catch {
alert('Get Latest Sample error')
}
}
UI component that calls the function:
export default function SampleAcceptedScreen(props) {
const { bottleID, equipmentID } = props.route.params
const [docBottleID, setDocBottleID] = useState('')
const [docEquipmentID, setDocEquipmentID] = useState('')
const [userName, setUserName] = useState('')
useEffect(() => {
try {
FirestoreService.getLatestAcceptedSample(bottleID, equipmentID).then((msg) => {
console.log(msg)
setDocBottleID(msg.bottleID)
setDocEquipmentID(msg.equipmentID)
setUserName(msg.userName)
})
}
catch {
console.log(error)
}
})
return (
<View style={styles.container} >
<CustomHeader title="Sample Accepted" navigation={props.navigation} isHome={false} />
<View style={styles.contentContainer} >
<Text style={styles.header} >Oil sample has been registered!</Text>
<Text style={styles.header2} >The following details have been associated with the sampling:</Text>
<Text>User: {userName} </Text>
<Text>Bottle barcode: {docBottleID} </Text>
<Text>Equipment barcode: {docEquipmentID} </Text>
<TouchableOpacity style={styles.button}
onPress={() =>
props.navigation.dispatch(
CommonActions.reset({
index: 1,
routes: [
{ name: 'HomeScreen' },
{
name: 'HomeScreen',
params: { bottleID: undefined, equipmentID: undefined }
}
]
})
)} >
<Text style={styles.buttonText} >Accept</Text>
</TouchableOpacity>
</View>
</View>
);
}
I solved the issue. I moved the return msg to here:
export const getLatestAcceptedSample = async (bottleID, equipmentID) => {
let msg = {}
try {
await db.collection('Oil Samples').orderBy('createdAt', 'desc').limit(1).get().then(querySnapshot => {
querySnapshot.forEach(documentSnapshot => {
const tempMsg = documentSnapshot.data()
if (bottleID === tempMsg.bottleID && equipmentID === tempMsg.equipmentID) {
msg = {
bottleID: tempMsg.bottleID,
equipmentID: tempMsg.equipmentID,
timestamp: tempMsg.createdAt?.toDate() ?? '',
userName: tempMsg.authorName,
userID: tempMsg.authorID,
title: tempMsg.title
}
console.log(msg)
} else {
alert("Fetching data from database failed")
}
})
})
return msg
}
catch {
alert('Get Latest Sample error')
}
}
Apparently I had written the logic mostly correct but the scope for the return wasn't correct.

How to get all JSON data inside the brackets using fetch?

I am newbie to react native and I would like to create a simple app to fetch JSON data.
Here is my json file.
[
{
"fruit": "Apple",
"size": "Large",
"color": "Red"
},
{
"fruit": "Orange",
"size": "big",
"color": "Orange"
}
]
Here is my react native code
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = { data: '' };
}
componentDidMount = () => {
fetch('https://othersite.my.json', {
method: 'GET'
})
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson);
this.setState({
data: responseJson
})
})
.catch((error) => {
console.error(error);
});
}
render() {
return (
<View style={styles.container}>
<Text>
{this.state.data}
//for debug {this.state.data.fruit}
</Text>
</View>
);
}
}
But it doesn't work.
Your fetch looks good in there. Considering you are able to fetch data from the API and set the state. You can use map() function to display your data
render(){
return (
<View style={styles.container}>
{this.state.data.map((item) => {
console.log(item.fruit)
console.log(item.size)
console.log(item.color)
})
</View>
);
}
If the json file is inside your react project, you can import the like this:
const fruits = require('path/to/json/my.json');
console.log(fruits[0].size);

How to remove duplicates from array in react native

The below code shows the array of duplicate data's , But I need a Unique data's from the array.
I tried many steps, but I can't find the solution:
See the below image of the output of duplicate received
JS File
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
storage: [],
};
this.renderData = this.renderData.bind(this);
}
renderData({ item, index }) {
const datas = Array.from(new Set(item.category));
return (
<View>
<Text>{datas}</Text>
</View>
);
}
componentDidMount() {
fetch('http://myjsonpage', {
method: 'post',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',},
body: JSON.stringify({
token: 'XXXXXX',
}),
}).then(response => { response.json().then(responseData => {
if (responseData.status === 1) {
this.setState({ datas:responseData.data}) ;
} else {
this.setState({ storage: [] });
}
});});}
render() {
return (
<View style={styles.continer}>
<View style={styles.heading}>
<Text style={styles.font}> Most Common Categories </Text>
</View>
<View style={styles.item}>
<FlatList data={this.state.datas} renderItem={this.renderData} />
</View>
</View>
);}}
Thanks in Advance..!!
There's many ways to remove duplicates from array, Use Sets to remove your duplicates.
const data = ['Renewal', 'Subscriptions', 'Subscriptions', 'Subscriptions', 'Renewal', 'Renewal']
const unique = new Set(data);
const uniqueData = [...unique]; // array
const data = ['Renewal', 'Subscriptions', 'Subscriptions', 'Subscriptions', 'Renewal', 'Renewal']
const uniqueData = [...new Set(data)];
console.log(uniqueData);
if (responseData.status === 1) {
this.setState({ datas: [...new Set(responseData.data)] }) ;
} else {
this.setState({ storage: [] });
}

Retrieving Array from API and filtering through in React

I have successfully called and passed the token to my API endpoint. However, I do not need both objects. I just want to work with the first index in the array that has fields. So I would like to retrieve all the details and print them out in the browser but for now all what can be printed is ID and type
I have tried filtering through the data array but it did not work.
var config = {
headers: {'Authorization': 'Bearer token'}
};
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
data: [],
}
}
componentDidMount() {
axios.get('https://api.transferwise.com/v1/profiles',config)
.then(response => {
if (response.status === 200 && response != null) {
this.setState({
data: response.data
});
} else {
console.log('problem');
}
})
.catch(error => {
console.log(error);
});
}
render() {
const { data } = this.state;
return (
<div >
{this.state.data.map(object => (
<p key={object.uid}>{object.id} {object.type}</p>
))}
</div>
)
}};
export default App;
Looks like your data consists of an array where each item can be an object with details of a different type.
To dynamically render the field values of each object you could do something like:
{this.state.data.map(({ id, type, details }) => {
return (
<>
<p key={id}>
{id} {type}
</p>
{Object.keys(details).map((key, index) => (
<p key={index}>{details[key]}</p>
))}
</>
);
})}
So it looks to me like you're not going deep enough in your mapped object.
which means you should access the details portion of the object to get the info you want
this.state.data.map(object => (
// The object data structure at this point should look like this
// {
// details: {firstName: 'firstExample', lastName: 'lastExample', ...},
// id: 'example'
// type: 'personal'
// } if you console.log(object) you should be able to see it
{<p key={object.details.id}>{object.details.id} {object.details.type}</p>
))}

Categories

Resources