data from object not rendering in any component in react native [duplicate] - javascript

I'm trying to get data from an array and using map function to render content. Look at
**{this.lapsList()}**
and the associated
**lapsList()**
function to understand what I'm trying to do. The result is nothing is displaying (Views under view, etc.) Here is my simplified code:
class StopWatch extends Component {
constructor(props) {
super(props);
this.state = {
laps: []
};
}
render() {
return (
<View style={styles.container}>
<View style={styles.footer}>
<View><Text>coucou test</Text></View>
{this.lapsList()}
</View>
</View>
)
}
lapsList() {
this.state.laps.map((data) => {
return (
<View><Text>{data.time}</Text></View>
)
})
}
_handlePressLap() {
console.log("press lap");
if (!this.state.isRunning) {
this.setState({
laps: []
})
return
}
let laps = this.state.laps.concat([{'time': this.state.timeElapsed}]);
this.setState({
laps: laps
})
console.log(laps);
}
}

Don't forget to return the mapped array , like:
lapsList() {
return this.state.laps.map((data) => {
return (
<View><Text>{data.time}</Text></View>
)
})
}
Reference for the map() method: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Try moving the lapsList function out of your class and into your render function:
render() {
const lapsList = this.state.laps.map((data) => {
return (
<View><Text>{data.time}</Text></View>
)
})
return (
<View style={styles.container}>
<View style={styles.footer}>
<View><Text>coucou test</Text></View>
{lapsList}
</View>
</View>
)
}

lapsList() {
return this.state.laps.map((data) => {
return (
<View><Text>{data.time}</Text></View>
)
})
}
You forgot to return the map. this code will resolve the issue.

Related

How can I pass a selected object from an array (firestore) to another class in react native?

I have a question about passing specific Objects from an array to another class in react native. If I press the button, all objects go to another class instead of the one I need, but I want the one which I pressed. Do I have to create a function for the selected object/ key or is it enough if I change something in the onPress={} method?
I need to change something here -> TouchableOpacity onPress={()=>this.props.navigation.navigate('detail', item,{})}> Item must be the document (firestore) with all the information I have, but how can I pass the object from the array only?
Here are also some pictures for a better understanding, thank you in advance
export default class foods extends Component {
constructor(props) {
super(props);
this.state = {
posts:[],
}
}
componentDidMount() {
StatusBar.setHidden(true)
this.subscriber = database.collection('users').onSnapshot(docs => {
let posts = []
docs.forEach(document => {
posts.push({
id: document.id,
...document.data(),
})
})
this.setState({posts})
console.log(posts)
})
}
render() {
return (
<ScrollView>
<View style={styles.container}>
{
this.state.posts.map((item) => {
return (
<View >
{
Object.keys(item.post).map((key) => {
return (
<View style={styles.card}>
<TouchableOpacity onPress={() => this.props.navigation.navigate('detail', item, {})}>
<Text>{item.firstName} {item.lastName}</Text>
<Image style={styles.cardImage} source={{ uri: item.post[key].image }} />
<Text>{item.post[key].essenname}</Text>
</TouchableOpacity>
</View>
)
})
}
</View>
)
})
}
</View>
</ScrollView>
);
}
}
export default class detail extends Component {
constructor(props) {
super(props);
this.state = {
post: [this.props.route.params]
}
};
componentDidMount() {
StatusBar.setHidden(true)
console.log('Array : ', this.state.post)
}
render() {
return (
<View style={styles.container}>
<ScrollView>
{this.state.post.map((item) => {
return (
Object.keys(item.post).map((key) => {
return (
<View style={styles.card}>
<Image style={styles.cardImage} source={{ uri: item.post[key].image }} />
<Text>{item.post[key].essenname}</Text>
</View>
)
})
)
})}
</ScrollView>
</View>
);
}
}
I want to pass either Post[0] or Post[1] but not both:
![](https://i.stack.imgur.com/3recX.png)
This is my output, which is the same output after navigating the item to the detail screen:
![](https://i.stack.imgur.com/WMqrd.png)
Detail screen on the right:
![](https://i.stack.imgur.com/gIX0V.png)
The document with the array 'post':
![](https://i.stack.imgur.com/dO1uQ.png)
There is no need to use Object.keys to loop trought your posts, just use item.post.
In your navigation params, just use a spred operator for the root key and pass the post selected: this.props.navigation.navigate('detail', {posts: {...this.state.posts, post: [p]}}).
In your detail component state your are missing to access the params, it should be:
this.state={
post:[this.props.route.params.posts]
}
and replace Object.keys with item.post

Connecting REST API in React Native

I am trying to learn how to connect APIs in React Native. I am using a sample API: https://reactnative.dev/movies.json
This is my code:
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
loading: true,
dataSource: [],
};
}
componentDidMount() {
return fetch("https://reactnative.dev/movies.json")
.then((response) => response.json())
.then((responseJson) => {
this.setState({
loading: false,
dataSource: responseJson.movies,
});
})
.catch((error) => console.log(error)); //to catch the errors if any
}
render() {
if (this.state.isLoading) {
return (
<View style={styles.container}>
<ActivityIndicator size="large" color="#0c9" />
</View>
);
} else {
let products = this.state.dataSource.map((val, key) => {
return (
<View key={key} style={styles.item}>
<Text>{val}</Text>
</View>
);
});
return (
<View style={styles.container}>
<Text>{products.title}</Text>
</View>
);
}
}
}
The problem occurs with my "products" variable. In debug mode, I was able to see the key and value pairs which were correct from the API. However, the products array is populated with objects rather than strings which are structured like this:
Object {$$typeof: Symbol(react.element), type: "RCTView", key: "0", …}
My code returns the following error: this.state.dataSource.map is not a function
EDIT:
The answer below worked for the API I was using. Now I am trying a different API structured like this:
{"prods":
{
"86400":{"slug":"86400","url":"/86400"},
"23andme":{"slug":"23andme","url":"/23andme"}
}}
I am having trouble with the mapping again. This returns an error:
return dataSource.map((val, key) => (
<View key={key} style={styles.item}>
<Text>{val.slug}</Text>
</View>
));
First, there is a small typo in your example. In your component's constructor you specify a loading state variable, but in your render function you're using isLoading. Second, you're not mapping over your data correctly. It just looks like you need to specify what aspects of each movie you care about in your render function. JSX can't handle displaying a full javascript object which is what <Text>{val}</Text> ends up being in your code. There are a few ways you can fix this. It's very common to just map over your results and display them directly.
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
loading: true,
dataSource: []
};
}
componentDidMount() {
return fetch("https://reactnative.dev/movies.json")
.then(response => response.json())
.then(responseJson => {
this.setState({
loading: false,
dataSource: responseJson.movies
});
})
.catch(error => console.log(error));
}
render() {
const { loading, dataSource } = this.state;
if (loading) {
return (
<View style={styles.container}>
<ActivityIndicator size="large" color="#0c9" />
</View>
);
}
return dataSource.map((movie, index) => (
<View key={movie.id} style={styles.item}>
<Text>{movie.title}</Text>
</View>
));
}
}
You could also pull this out to a renderMovies method, which might help since you are trying to display these in a styled container.
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
loading: true,
dataSource: []
};
}
componentDidMount() {
return fetch("https://reactnative.dev/movies.json")
.then(response => response.json())
.then(responseJson => {
this.setState({
loading: false,
dataSource: responseJson.movies
});
})
.catch(error => console.log(error));
}
renderMovies() {
const { dataSource } = this.state;
return dataSource.map((movie, index) => (
<View key={movie.id} style={styles.item}>
<Text>{movie.title}</Text>
</View>
));
}
render() {
const { loading } = this.state;
if (loading) {
return (
<View style={styles.container}>
<ActivityIndicator size="large" color="#0c9" />
</View>
);
}
return (
<View style={styles.container}>
{this.renderMovies()}
</View>
);
}
}
I have used Object.values() to restructure the object into an array
componentDidMount() {
return fetch("https://reactnative.dev/movies.json")
.then((response) => response.json())
.then((responseJson) => {
this.setState({
loading: false,
dataSource: Object.values(responseJson.movies), //changed this
});
})
.catch((error) => console.log(error));
}
Try simple way. This code uses modern React practice and helps you to brush up your React skills in general. Give a try.
import React, {useState, useEffect} from 'react';
import { Text, View, StyleSheet } from 'react-native';
import axios from 'axios'; //for fetching data
export default function App() {
//React Hook for state
const [ data, setData ] = useState ([]);
//React Hook Instead Of ComponentDidMount
useEffect(() => {
const fetchData = async () => {
const result = await axios(
"https://reactnative.dev/movies.json",
);
setData(result.data.movies);
};
fetchData();
}, []);
return (
<View>
<Text>{JSON.stringify(data)}</Text>
</View>
);
}

Fetching data from function into <View> component inside the render method

I tried to fetch the data from function inside render, when I use alert() it works, but when I try to return real text it not shown any thing
the code I work with:
export default class App extends Component {
renderResualts(){
db.find({}, function (err, docs) {
return docs.map(function(d){
return(
<Text>{d.name}</Text>
)
})
})
}
render() {
return (
<View style={styles.container}>
{ this.renderResualts() }
</View>
);
}
}
--
UPDATED CODE:
export default class App extends Component {
constructor(props){
super(props)
this.state = {graves:[]}
}
componentDidMount(){
db.find({}, function (err, docs) {
this.setState({graves:docs})
})
}
renderResults(){
return this.state.graves.map(grave =>
<Text>{grave.name}</Text>
)
}
render() {
return (
<View style={styles.container}>
{ this.renderResults() }
</View>
);
}
}
It should be shown these data :
{
_id: 1,
name: 'Parturient',
year: 2017
}, {
_id: 2,
name: 'Dapibus',
year: 2017
}
inside text like so: ParturientDapibus
try this
renderResults(){
return (
<View>
this.state.graves.map(grave =>
<Text>{grave.name}</Text>
)
</View>
);
}
By passing the data to State like so:
export default class App extends Component {
constructor(props){
super(props)
this.state = {graves:[]}
}
componentDidMount(){
db.find({}, (err, docs)=> {
this.setState({graves:docs})
})
}
renderResults(){
return this.state.graves.map(grave =>
<Text key={grave._id}>{grave.name}</Text>
)
}
render() {
return (
<View style={styles.container}>
{ this.renderResults() }
</View>
);
}
}

How to Fetch APIs and Print first element in response Array?

My React Native app fetch API data and I need to print the first index of response but it's not, and gets all of the "ozone" for example in all child of the parent Array and when I print val[0] when Mapping I have nothing printed
My Code|
export default class App extends Component {
constructor(props) {
super(props);
this.state = { isLoading: true, dataSource: null };
}
async componentDidMount() {
let API_WEATHER =
"https://api.weatherbit.io/v2.0/forecast/daily?city=Raleigh,NC&key={API_KEY}";
fetch(API_WEATHER)
.then(response => response.json())
.then(responseJson => {
console.log(responseJson.data);
this.setState({
isLoading: false,
dataSource: responseJson.data
});
})
.catch(error => {
console.log(error);
});
}
render() {
if (this.state.isLoading) {
return (
<View style={{ flex: 1, padding: 20 }}>
<ActivityIndicator size="large" />
</View>
);
}
let weather= this.state.dataSource.map((val, key) => {
return (
<Text key={key}>
{val.ozone}
</Text>
);
});
return (
<ScrollView style={styles.container}>
<ScrollView>
<View>
<Text>{weather}</Text>
</View>
</ScrollView>
</ScrollView>
);
}
In this part of the code when i log the respone JSON obj
.then(responseJson => {
console.log(responseJson.data);
console.log(responseJson.data[0]);
console.log(responseJson.data[0].datetime);
}
i have what i need, but when print them in View i have Erroe
look at the Images
You're probably the first key of the object.
obj[Object.keys(obj)[0]];
Also, you can use
Try the for … in loop and break after the first iteration
for (var prop in object) {
// object[prop]
break;
}

how to show a component depending of picker value selected? [React native]

I'm trying to make a game with react native and I want to show a different options when i change the picker value.
basically when I select the first option on the picker a component has to appear and when I select the second one another component.
I tried this function but not working
pickerOptionText = () => {
if (this.state.PickerValueHolder==this.state.filter[0]) {
return (
<Text>{instructions[2]}</Text>
);
}else {
return (
<Text>{instructions[1]}</Text>
);
}
return null;
}
here is my code
export default class Facil extends Component {
constructor(props)
{
super(props);
this.state = {
isLoading: true,
PickerValueHolder : '',
filter: [
{
"option":"Palabras por categoria"
},
{
"option":"Palabras por caracteres"
}
],
dataSource:[]
}
}
componentDidMount() {
return fetch(API_URL)
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson
})
})
.catch((error) => {
console.error(error);
});
}
render() {
const resizeMode = 'stretch';
pickerOptionText = () => {
if (this.state.PickerValueHolder==this.state.filter[0]) {
return (
<Text>{instructions[2]}</Text>
);
}else {
return (
<Text>{instructions[1]}</Text>
);
}
return null;
}
return (
<View style={styles.container}>
<Image source={require('../../Images/HomeLayout.png')}
style={styles.imagen}
/>
<View style={styles.mView}>
<View style={styles.panel}>
<Text style={styles.titlePanel}>MODO FACIL</Text>
<Text style={styles.instructions}>{instructions[0]}</Text>
<View style={styles.picker}>
<Picker
selectedValue={this.state.PickerValueHolder}
style={ {height: '100%',width: '100%'}}
mode="dropdown"
onValueChange={(itemValue, itemIndex) => this.setState({PickerValueHolder: itemValue})} >
{ this.state.filter.map((item, key)=>(
<Picker.Item label={item.option} value={item.option} key={key} />)
)}
</Picker>
</View>
<View style={styles.gameOpt}>
<Text>[dynamic options]</Text>
{pickerOptionText}
</View>
</View>
</View>
<TouchableOpacity style={styles.button}><Text style={styles.btnText}>Play!</Text></TouchableOpacity>
</View>
);
}
}
You forgot '()'.
pickerOptionText is a function, not a React component.
<Text>[dynamic options]</Text>
{pickerOptionText}
to:
<Text>[dynamic options]</Text>
{pickerOptionText()}
You can try using Conditional Rendering of JSX, by this you can use ternary operator and a simple if condition. this is written as:
{this.state.PickerValueHolder==this.state.filter[0] ?
<Text>{instructions[2]}</Text>
:<Text>{instructions[1]}</Text>
}
and if you need simple if condition then,
{ condition == true && <Text>your text here</Text>
}

Categories

Resources