React native pure chart dynamic data problem - react-native

I'm trying to load some data to a chart using https://github.com/oksktank/react-native-pure-chart
Trying to load Json data from api but seem to get undefined only, what might be the problem?
constructor(props){
super(props);
this.state = { isLoading: true}
}
componentDidMount(){
return fetch('https://api.mockaroo.com/api/12a7ead0?count=20&key=8ba88000')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson.Weight,
}, function(){
});
})
.catch((error) =>{
console.error(error);
});
}
render() {
return (
<SafeAreaView style={{flex:1}}>
<PureChart data={this.state.dataSource} type='line' />
</SafeAreaView>
);
}
}

The data you are providing to PureChart is not correct.
Here is the working example: https://snack.expo.io/#msbot01/moody-orange
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';
import PureChart from 'react-native-pure-chart';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = { isLoading: true };
}
componentDidMount() {
return fetch('https://api.mockaroo.com/api/12a7ead0?count=20&key=8ba88000')
.then(response => response.json())
.then(responseJson => {
console.log(JSON.stringify(responseJson))
var temp = [];
for (var i = 0; i < responseJson.length; i++) {
console.log(responseJson[i].Weight)
temp.push(responseJson[i].Weight)
}
this.setState({
dataSource:temp
})
})
.catch(error => {
console.error(error);
});
}
render() {
return (
<View style={styles.container}>
<PureChart data={this.state.dataSource} type="line" />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
});

Related

List Item Data is populated but the data does not display on flat list

In this FlatList, the list items Display but they are blank.
I have set break points and the data is there, but it only displays blank list items.
I think the issue may arise when I am setting the array empty, then it does not re-render properly when the fetch is complete.
Crypto Component
import {StyleSheet, FlatList} from 'react-native';
import {getCrypto} from '../api_service/crypto';
import CryptoItem from '../data/cryptoItem';
export default class CryptoMarket extends Component {
constructor(props) {
super(props);
this.state = {cryptos: [], refreshing: true};
this.fetchCrypto = this.fetchCrypto.bind(this);
}
componentDidMount() {
this.fetchCrypto();
}
fetchCrypto() {
getCrypto()
.then(cryptos => this.setState({cryptos, refreshing: false}))
.catch(() => this.setState({refreshing: false}));
}
handleRefresh() {
this.setState(
{
refreshing: true,
},
() => this.fetchCrypto(),
);
}
render() {
return (
<FlatList
data={this.state.cryptos}
renderItem={({item}) => <CryptoItem crypto={{item}} />}
keyExtractor={item => item.name}
refreshing={this.state.refreshing}
onRefresh={this.handleRefresh.bind(this)}
/>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#0f0f0f',
},
contentContainer: {
marginTop: 50,
alignItems: 'center',
paddingHorizontal: 20,
},
title: {
fontSize: 20,
color: '#fff',
},
});
Fetch API
export async function getCrypto() {
try {
const fetchCrypto = await fetch(
'https://api.nomics.com/v1/currencies/ticker?key=***&ids=BTC,ETH,XRP',
);
const displayCrypto = await fetchCrypto.json();
console.log(displayCrypto);
return displayCrypto;
} catch (error) {
throw error;
}
}
List Item
import React, {Component} from 'react';
import {ListItem} from 'react-native-elements';
export default class CryptoItem extends Component {
render() {
const {name, logo_url, price} = this.props.crypto;
return (
<ListItem
title={name}
text={'Price : ' + price}
leftAvatar={{source: {uri: logo_url}}}
bottomDivider={true}
/>
);
}
}

Why is my redux props nested inside of another?

When I call my props I have to use the below. Is this normal? or am I doing something that's off? everything works. props has data, it's just alway nested in something and I have to pull it out from multiple levels
props.posts.posts
Is there a reason why it's nested in a posts? Am I doing something redundant?
import { ScrollView, StyleSheet, Text, View, FlatList } from 'react-native';
import Feed from './components/Feed';
import { Provider } from 'react-redux';
import store from './store/configureStore'
function App() {
return (
<Provider store={store}>
<View style={styles.container}>
<Feed />
</View>
</Provider>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default App;
feed.js
import React, { useState, useEffect } from "react";
import { StyleSheet, Text, View, ScrollView, FlatList} from "react-native";
import { connect } from 'react-redux';
import { fetchAPI } from '../actions';
const Feed = (props) => {
useEffect(() => {
props.fetchAPI();
}, []);
console.log(props)
return (
<View style={styles.container}>
<FlatList
data={props.posts.posts}
renderItem={({item, index}) => (
<View key={index}>
<Text>{item.id}</Text>
</View>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});
const dispatchToProps = (dispatch) => {
return {
fetchAPI: () => dispatch(fetchAPI()),
};
};
const stateToProps = (state) => ({
posts: state.posts,
});
export default connect(stateToProps, dispatchToProps)(Feed);
action
import { FETCH_POSTS } from "./types";
export const fetchAPI = () => (dispatch) => {
fetch("https://jsonplaceholder.typicode.com/posts")
.then((response) => response.json())
.then((response) => {
dispatch({
type: FETCH_POSTS,
payload: response,
// again don't know where payload is coming from
});
})
.catch((error) => console.log(error));
};
reducer.js
import { FETCH_POSTS } from '../actions/types';
const initialState = {
posts: []
}
export default (state = initialState, action) => {
switch(action.type) {
case FETCH_POSTS:
return {...state, posts: action.payload}
default:
return state;
}
}
Yes. your approach works fine too. However I recommend some minor changes.
Action
import { FETCH_POSTS } from "./types";
export const fetchAPI = () => (dispatch) => {
fetch("https://jsonplaceholder.typicode.com/posts")
.then((response) => response.json())
.then(({posts}) => { //changes added here
dispatch({
type: FETCH_POSTS,
payload: posts, //changes added here
});
})
.catch((error) => console.log(error));
};
Feed.js
import React, { useState, useEffect } from "react";
import { StyleSheet, Text, View, ScrollView, FlatList} from "react-native";
import { connect } from 'react-redux';
import { fetchAPI } from '../actions';
const Feed = (props) => {
useEffect(() => {
props.fetchAPI();
}, []);
console.log(props)
return (
<View style={styles.container}>
<FlatList
data={props.posts} //changes added here
renderItem={({item, index}) => (
<View key={index}>
<Text>{item.id}</Text>
</View>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});
const dispatchToProps = (dispatch) => {
return {
fetchAPI: () => dispatch(fetchAPI()),
};
};
const stateToProps = (state) => ({
posts: state.posts,
});
export default connect(stateToProps, dispatchToProps)(Feed);
Hope this helps. Let me know if the code works or not. Cheers!

React Native - state is not saved in object

Im trying out React Native an now im fetching a weather forecast from openweather API. the data is getting fetched after the user type in the city an click the button.
The problem is that i am trying to save the response to the state objects property "forecast" but its not beeing saved.
What am i doing wrong?
import React, {Component} from 'react';
import {StyleSheet, Text ,TextInput, View, Button} from 'react-native';
export default class App extends Component {
constructor(props){
super(props);
this.state = {
text:"",
forecast:null,
hasData: false
}
}
userTextChange = (input) => {
this.setState({
text:input
})
}
getMovies = () => {
var url = 'https://api.openweathermap.org/data/2.5/weather?q='+this.state.text+'&units=metric&appid=7d6b48897fecf4839e128d90c0fa1288';
fetch(url)
.then((response) => response.json())
.then((response) => {
this.setState = ({
forecast:response,
hasData:true
})
console.log(response) <-- This is a json reponse with one object
})
.catch((error) => {
console.log("Error: ",error);
});
}
render() {
return (
<View style={styles.container} >
<TextInput
style={{width:'80%',borderRadius:8,marginTop:70,height:60,backgroundColor:'#f1f1f1',textAlign:'center',borderWidth:1,borderColor:'#ccc'}}
placeholder=""
onChangeText={this.userTextChange}
/>
<Button
title="Get forecats"
style={{backgroundColor:'#000',height:50,width:'50%',marginTop:30,marginBottom:30}}
onPress={()=>this.getMovies()}
/>
<View style={{width:'90%',height:'68%', backgroundColor:'rgba(0,0,0,0.5)',alignItems:'center',paddingTop:20}}>
<Text style={{color:'#000',fontSize:22}}>{this.state.forecast.name}</Text> <-- THIS IS NULL
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex:1,
alignItems:'center'
},
});
Herer is the JSON response frpm openweather API
The following line:
this.setState = ({
forecast:response,
hasData:true
})
should be:
this.setState({
forecast:response,
hasData:true
})
You should also consider initializing forecast in state to an empty object.

Exporting JSON from fetch in React Native

I am working on exporting the JSON I get from a fetch. I know I have a binding issue, but I'm not completely sure on how I should proceed to bind my function to the current component. I have a quick example at this URL https://snack.expo.io/#mcmillster/c21pbG.
app.js
import React from 'react';
import { FlatList, ActivityIndicator, Text, View } from 'react-native';
import { getMovies } from './utility.js';
export default class FetchExample extends React.Component {
constructor(props){
super(props);
this.state ={
isLoading: true,
}
this.getMovies = getMovies.bind(this)
}
componentDidMount(){
this.getMovies;
}
render(){
if(this.state.isLoading){
return(
<View style={{flex: 1, padding: 100}}>
<ActivityIndicator/>
</View>
)
}
return(
<View style={{flex: 1, paddingTop:20}}>
<FlatList
data={ this.state.data }
renderItem={({item}) => <Text>{item.title}, {item.releaseYear}
</Text>}
keyExtractor={({id}, index) => id}
/>
</View>
);
}
}
utility.js
export function getMovies() {
return fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
data: responseJson.movies,
}, function(){
});
})
.catch((error) =>{
console.error(error);
});
}
I think you should not try to set the state from your fetch function. Just call it, return data and handle them in your component.
app.js
[...]
private getMovies = async() => {
const movies = await getMovies();
if(movies){
this.setState({...})
}
componentDidMount(){
this.getMovies();
}
utility.js
export function getMovies() {
return fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
return responseJson.movies;
})
.catch((error) =>{
console.error(error);
return;
});
}
In your componentDidMount lifecycle hook, you're not calling the getMovies function, you're just referencing it. Change this.getMovies to this.getMovies()
Solution
componentDidMount(){
this.getMovies();
}

React Native: ListView.DataSource is not updating

I am trying to update ListView.DataSource after fetching data from server but its not happening. I have two components, one is imported in other.
From base component I am trying to update ListView.DataSource in other component. Here is my code.
index.android.js
import React, { Component } from "react";
import { ListView, View, Button, AppRegistry } from "react-native";
import OtherComponent from "./Components/OtherComponent";
class MyApp extends Component {
constructor(props) {
super(props);
this.state = {
movies: [{ title: "ABCD" }, { title: "EFGH" }]
};
}
getTopics = () => {
fetch("https://facebook.github.io/react-native/movies.json")
.then(response => response.json())
.then(responseText => {
console.log(responseText.movies);
this.setState({
movies: responseText.movies
});
})
.catch(error => {
console.warn(error);
});
};
render() {
return (
<View>
<Button
onPress={this.getTopics}
title="Get Topics"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
<OtherComponent movies={this.state.movies} />
</View>
);
}
}
AppRegistry.registerComponent("MyApp", () => MyApp);
OtheComponent.js
import React, { Component } from "react";
import { View, ListView, Text, StyleSheet, Button } from "react-native";
export default class FormativeRevisionList extends Component {
constructor(props) {
super(props);
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
});
this.state = {
dataSource: ds.cloneWithRows(props.movies)
};
}
render() {
return (
<View>
<ListView
style={styles.listContainer}
dataSource={this.state.dataSource}
renderRow={rowData => (
<View>
<Text style={styles.listItem}>{rowData.title}</Text>
</View>
)}
/>
</View>
);
}
}
const styles = StyleSheet.create({
listContainer: {
paddingTop: 22
},
listItem: {
fontSize: 30,
fontWeight: "bold",
textAlign: "center"
}
});
In your code, you only set your dataSource in contructor of FormativeRevisionList, this mean FormativeRevisionList will only render the given movies when your first render it.
To render new list after you press Get Topics button , you need to set the dataSource again when it receive new props, this can be achieve by setting it in FormativeRevisionList componentWillReceiveProps
componentWillReceiveProps(nextProps) {
if (nextProps.movies !== this.props.movies) {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(nextProps.movies)
})
}
}
You can read more about componentWillReceiveProps from here