I have some code that does not work as i expect, when i click the favorite icon, its supposed to save to async Storage. The code works to select the movies from the flatlist, where i have the problem is saving it to asyncStorage and then when i click the page to display the selected favorite movie in a flat list nothing shows up.
The homepage to show the movies code :
Home.js
import React, { Component } from 'react';
import { StyleSheet, Platform, View, ActivityIndicator, FlatList, Text, Image, Alert, LayoutAnimation, YellowBox , Button , AsyncStorage } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
export default class Home extends Component {
constructor(props) {
super(props);
this.state = {
UrlImage : '',
movie_desc : '',
favourite : false
};
}
GetItem (movie_description) {
Alert.alert(movie_description);
}
SaveData = async() =>
{
const movieData = {
UrlImage : this.state.UrlImage,
movie_desc : this.state.movie_desc
};
AsyncStorage.setItem('movie',JSON.stringify(movieData));
}
ShowMovies = () =>{
return fetch('https://uncoiled-crust.000webhostapp.com/api/movies_db.php')
.then((response) => response.json())
.then((responseJson) => {
const result = responseJson.map((value, index) => ({
...value,
isFavourite: 0
}))
this.setState({
isLoading: false,
dataSource: result
}, function() {
// In this block you can do something with new state.
});
})
.catch((error) => {
console.error(error);
});
}
componentWillMount()
{
const { movie_desc, UrlImage, favorite } = this.props;
this.setState({ movie_desc, UrlImage, favorite });
}
SelectItem(movie_desc){
Alert.alert(movie_desc);
}
componentWillUpdate() {
LayoutAnimation.easeInEaseOut();
}
componentDidMount(){
this.ShowMovies();
}
FlatListItemSeparator = () => {
return (
<View
style={{
height: .5,
width: "100%",
backgroundColor: "#000",
}}
/>
);
}
changeisFavorite = async (item, index) => {
let arr = [...this.state.dataSource]
arr[index].isFavorite = item.isFavorite == 1 ? 0:1;
this.setState({ dataSource: arr });
this.SaveData();
}
render()
{
const { movie_desc, UrlImage, favorite } = this.state;
return (
<View style={styles.MainContainer}>
<FlatList
data={ this.state.dataSource }
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem={({item,index}) =>
<View style={{flex:1, flexDirection: 'row'}}>
<Icon
name={item.isFavorite == 1 ? 'heart' : 'heart-o'}
color={item.isFavorite == 1 ? '#F44336' : 'rgb(50, 50, 50)'}
size={30}
style={{ marginBottom: 10, marginTop: 20 }}
onPress={() => this.changeisFavorite(item, index)}
/>
<Image source = {{ uri: item.url_image}} style={styles.imageView} />
<Text style={styles.textView} >{item.movie_description}</Text>
</View>
}
/>
</View>
);
}
}
const styles = StyleSheet.create({
MainContainer :{
justifyContent: 'center',
flex:1,
margin: 5,
marginTop: (Platform.OS === 'ios') ? 20 : 0,
},
imageView: {
width: '50%',
height: 350 ,
margin: 7,
borderRadius : 7
},
textView: {
width:'50%',
textAlignVertical:'center',
padding:10,
color: '#000'
}
});
Now this is the Favorites Area to display the movies in Flatlist
ShowFavorites.js
import React, { Component } from 'react';
import { StyleSheet, Platform, View, ActivityIndicator, FlatList, Text, Image, Alert, LayoutAnimation, YellowBox , Button , AsyncStorage } from 'react-native';
export default class Favourites extends Component {
constructor(props) {
super(props);
this.state = {
data : []
};
}
FlatListItemSeparator = () => {
return (
<View
style={{
height: .5,
width: "100%",
backgroundColor: "#000",
}}
/>
);
}
componentDidMount() {
AsyncStorage.getItem('movie').then(data => this.setState({ data }));
}
render() {
return (
<View styles={styles.MainContainer}>
<FlatList
data={ this.state.data }
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem={({item}) =>
<View style={{flex:1, flexDirection: 'row'}}>
<Image source = {{ uri: item.url_image }} style={styles.imageView} />
<Text style={styles.textView} >{item.movie_description}</Text>
</View>
}
keyExtractor={(item, index) => index.toString()}
/>
</View>
);
}
}
const styles = StyleSheet.create({
MainContainer :{
justifyContent: 'center',
flex:1,
margin: 5,
marginTop: (Platform.OS === 'ios') ? 20 : 0,
},
imageView: {
width: '50%',
height: 100 ,
margin: 7,
borderRadius : 7
},
textView: {
width:'50%',
textAlignVertical:'center',
padding:10,
color: '#000'
}
});
Is there something I am not doing very correctly? I need to be point in the right direction here.
Edits
Now I have edited the code to Look like this , and I am getting this as Error :
source.uri should not be an empty string
My Code for both the Home.js and Showfavourites.js Looks like this
Home.js
import React, { Component } from 'react';
import { StyleSheet, Platform, View, ActivityIndicator, FlatList, Text, Image, Alert, LayoutAnimation, YellowBox , Button } from 'react-native';
import AsyncStorage from "@react-native-async-storage/async-storage";
import Icon from 'react-native-vector-icons/FontAwesome';
export default class Home extends Component {
constructor(props) {
super(props);
this.state = {
url_image : '',
movie_description : '',
favourite : false
};
}
GetItem (movie_description) {
Alert.alert(movie_description);
}
SaveData = async () =>
{
const movieData = {
UrlImage : this.state.url_image,
movie_desc : this.state.movie_description
};
await AsyncStorage.setItem('@movie',JSON.stringify(movieData));
}
ShowMovies = () =>{
return fetch('https://uncoiled-crust.000webhostapp.com/api/movies_db.php')
.then((response) => response.json())
.then((responseJson) => {
const result = responseJson.map((value, index) => ({
...value,
isFavourite: 0
}))
this.setState({
isLoading: false,
dataSource: result
}, function() {
// In this block you can do something with new state.
});
})
.catch((error) => {
console.error(error);
});
}
componentWillMount()
{
const { movie_description, url_image, favorite } = this.props;
this.setState({ movie_description, url_image, favorite });
}
SelectItem(movie_description){
Alert.alert(movie_description);
}
componentWillUpdate() {
LayoutAnimation.easeInEaseOut();
}
componentDidMount(){
this.ShowMovies();
}
FlatListItemSeparator = () => {
return (
<View
style={{
height: .5,
width: "100%",
backgroundColor: "#000",
}}
/>
);
}
changeisFavorite = async (item, index) => {
let arr = [...this.state.dataSource]
arr[index].isFavorite = item.isFavorite == 1 ? 0:1;
this.setState({ dataSource: arr });
this.SaveData();
}
render()
{
const { movie_description, url_image, favorite } = this.state;
return (
<View style={styles.MainContainer}>
<FlatList
data={ this.state.dataSource }
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem={({item,index}) =>
<View style={{flex:1, flexDirection: 'row'}}>
<Icon
name={item.isFavorite == 1 ? 'heart' : 'heart-o'}
color={item.isFavorite == 1 ? '#F44336' : 'rgb(50, 50, 50)'}
size={30}
style={{ marginBottom: 10, marginTop: 20 }}
onPress={() => this.changeisFavorite(item, index)}
/>
<Image source = {{ uri: item.url_image}} style={styles.imageView} />
<Text style={styles.textView} >{item.movie_description}</Text>
</View>
}
/>
</View>
);
}
}
const styles = StyleSheet.create({
MainContainer :{
justifyContent: 'center',
flex:1,
margin: 5,
marginTop: (Platform.OS === 'ios') ? 20 : 0,
},
imageView: {
width: '50%',
height: 350 ,
margin: 7,
borderRadius : 7
},
textView: {
width:'50%',
textAlignVertical:'center',
padding:10,
color: '#000'
}
});
As for the show Favourites it Looks Like this
import React, { Component } from 'react';
import { StyleSheet, Platform, View, ActivityIndicator, FlatList, Text, Image, Alert, LayoutAnimation, YellowBox , Button } from 'react-native';
import AsyncStorage from "@react-native-async-storage/async-storage";
export default class Favourites extends Component {
constructor(props) {
super(props);
this.state = {
data : [] ,
url_image : '' ,
movie_description : ''
};
}
FlatListItemSeparator = () => {
return (
<View
style={{
height: .5,
width: "100%",
backgroundColor: "#000",
}}
/>
);
}
componentDidMount() {
AsyncStorage.getItem('movie').then(data => this.setState({ data }));
}
render() {
return (
<View styles={styles.MainContainer}>
<FlatList
data={ this.state.data }
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem={({item}) =>
<View style={{flex:1, flexDirection: 'row'}}>
<Image source = {{ uri: this.state.url_image }} style={styles.imageView} />
<Text style={styles.textView} >{this.state.movie_description}</Text>
</View>
}
keyExtractor={(item, index) => index.toString()}
/>
</View>
);
}
}
const styles = StyleSheet.create({
MainContainer :{
justifyContent: 'center',
flex:1,
margin: 5,
marginTop: (Platform.OS === 'ios') ? 20 : 0,
},
imageView: {