React Native fetch request is not displaying user's post properties - json

Just a simple React Native fetch request to MongoDB database. I'm trying to display dynamic JSON properties for a user's post, for example postedBy, title, etc. But when I set something like title or description I get nothing at all, just blankness.
Post.js
const mongoose = require('mongoose')
const bcrypt = require('bcrypt')
const { ObjectId } = mongoose.Schema.Types
const postSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
postdesc: {
type: String,
required: true
},
img: {
type: String,
required: true
},
postedBy: {
type: ObjectId,
ref: "User"
}
})
mongoose.model("Post", postSchema)
fetch api code
router.get('/allposts', requireLogin, (req, res)=>{
Post.find()
.populate('postedBy', '_id username')
.then( posts =>{
res.json({ posts })
})
.catch( err=>{
console.log(err)
})
})
fetch code
const [ data, setData ] = useState([])
useEffect(()=>{
AsyncStorage.getItem('user')
.then(async (data) => {
fetch('http://10.0.2.2:3000/allposts', {
headers: {
'Authorization': 'Bearer ' + JSON.parse(data).token
}
}).then(res=>res.json())
.then( result=>{
console.log(result)
setData(result.posts)
})
})
}, [])
return code
return(
<View style={styles.container}>
<View style={styles.c1}>
{
data.map(( item )=>{
return(
<View key={item}>
<Text style={styles.postedBy} >{ data.postedBy }</Text>
<Text style={styles.title} >{ data.title }</Text>
</View>
)
})
}
</View>
</View>
)
}
What I want is: The title of my post is "Here is a title from db".
What I'm getting is: The title of my post is [Blank space] .
Note: the console.log(result) is showing the post's json in console just fine.
LOG {"posts": [{"__v": 0, "title": "Here is a title"`...etc, etc }]}

Related

Objects are not valid as a React child (found: object with keys { my keys })

when I submit my form with the const onSubmit, I fetch data. If the submit form is ok, I want to extract the data I get from my api. So I use, setState reponse : my data, and then I want to pass this data (reponse) to the component SingleLayout.
But it doesn't work. I get this error : [Error: Objects are not valid as a React child (found: object with keys {ID, Post Title, post_date, Prix, Surface, Ville, Category, featured_image, mandats_signes, date_de_signature_du_compromis}). If you meant to render a collection of children, use an array instead.]
Here the code :
export default class QueryChild extends Component {
state = {
username: "",
password: "",
isLogged: null,
email: "",
reponse: '',
id: 4577
}
constructor(props) {
super(props);
this.render();
}
onSubmit = async() => {
const fetchValue = 'myAPI/suivi-dossier?' + 'username=' + this.state.username + '&password=' + this.state.password + '&id=' + this.state.id
try {
await fetch(fetchValue, {
method: 'GET'
})
.then((response) => response.json())
.then((responseJson) => {
if(responseJson.success === true) {
// I want to extract this :
this.setState({ reponse: responseJson.message })
this.setState({ isLogged: true })
} else {
this.setState({reponse : responseJson.message });
console.log(this.state.reponse)
}
// this.setState({
// data: responseJson
// })
})
.catch((error) => {
console.error(error);
});
} catch (err) {
console.log(err)
}
}
render() {
if(this.state.isLogged === true) {
// when user is Logged, I want to pass this.state.reponse to my component SingleLayout
// but I get the error : [Error: Objects are not valid as a React child
// (found: object with keys {ID, Post Title, post_date, Prix, Surface, Ville,
// Category, featured_image, mandats_signes, date_de_signature_du_compromis}). If you
// meant to render a collection of children, use an array instead.]
const SingleComponent = this.state.reponse.map(message => <SingleLayout key={message.ID} table={message}/> )
return (
<SafeAreaView>
{SingleComponent}
</SafeAreaView>
);
} else {
return (
<View style={styles.container}>
<ScrollView>
<ImageBackground source={image} resizeMode="cover" style={styles.image}>
<Spacer taille={70} />
<View style={styles.content}>
<Image
style={styles.imgLogo}
source={require('../../logo.png')}
/>
<Text style={styles.logo}>Pour des raisons de sécurité, veuillez entrer vos Identifiants</Text>
<View style={styles.inputContainer}>
<Text style={styles.textBasique}>{this.state.reponse}</Text>
<TextInput
placeholder='Identifiant ou adresse email'
style={styles.input}
value={this.state.username}
onChangeText={val => this.setState({ username: val})}
/>
<TextInput
placeholder='Mot de passe'
style={styles.input}
value={this.state.password}
secureTextEntry= {true}
onChangeText={val => this.setState({ password: val})}
/>
<Spacer taille={10} />
<Button title='Se Connecter' onPress={this.onSubmit}/>
<Spacer taille={10} />
</View>
</View>
<Spacer taille={200} />
</ImageBackground>
</ScrollView>
</View>
)
}
}
}
Thank you.
The response that comes from the server is an object. Since the "map" function only works with an array so, if you want to run this code you've to wrap "responseJson.message" into the array.
if(responseJson.success === true) {
this.setState({ reponse: [responseJson.message] })
this.setState({ isLogged: true })
}
Yes I get similar error after applying the solution because I found that the error comes from the setState reponse. So I added JSON.stringify and now the error is gone.
The code of Single Layout :
const SingleLayout = (props) => {
let id = props.id
let table = props.table
console.log(table)
const { colors } = useTheme();
return (
<View style={[styles.container, {backgroundColor: colors.background}]}>
<Text>Bravo</Text>
</View>
)
}
Now with the solution : const SingleComponent = Object.keys(this.state.reponse).map(key => )
it works but it send caracters one by one
SO I finally solved my problem :
the code i change :
QueryChild.tsx :
if(responseJson.success === true) {
//here :
this.setState({ reponse: JSON.stringify(responseJson.message) })
this.setState({ isLogged: true })
and I directly return SingleLayout like that :
return (
<SafeAreaView>
<SingleLayout table={this.state.reponse} />
</SafeAreaView>
Now I can access this.state.reponse into my SingleLayout :
const SingleLayout = (props) => {
let id = props.id
let table = props.table
const myObj = JSON.parse(table);
console.log(myObj[0].mandats_signes)
console.log(myObj[0].ID)
console.log(myObj[0].Category)
//etc...
const { colors } = useTheme();
return (
<View style={[styles.container, {backgroundColor: colors.background}]}>
<Text>Bravo</Text>
</View>
)
}
it's not a good practice to pass JSON and then parse.
I solved it and here is the link with the same solution that I presented to you:
https://codesandbox.io/s/peaceful-bouman-qyi5y?file=/src/App.js

Data is not going in database in MERN

Data is not going in Database in MERN ---
Everything is looking fine and also got status 200 and alert "post created" but data is not going in my database.
How to debug this error. I have tried all solutions. At least tell me the possible reasons for this error. it will help me a lot.
Schema
const mongoose = require("mongoose");
const postSchema = new mongoose.Schema({
title: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
picture: {
type: String,
required: false,
},
username: {
type: String,
required: true,
},
category: {
type: String,
required: false,
},
createDate: {
type: Date,
default: Date.now,
},
})
const post = new mongoose.model('post', postSchema);
module.exports = post;
server router
const express = require("express");
const router = express.Router();
const post = require("../schema/post-schema");
router.post('/create', async(req,res) => {
try{
console.log(req.body);
const { title, description, picture, username, category, createDate } = req.body;
const blogData = new post({
title:title,
description:description,
picture:picture,
username:username,
category:category,
createDate:createDate
});
console.log("user " + blogData);
const blogCreated = await blogData.save();
if(blogCreated)
{
return res.status(200).json({
message: "blog created successfully"
})
}
console.log("post "+post);
} catch(error){
res.status(500).json('Blog not saved '+ error)
}
})
module.exports = router;
client file
const initialValues = {
title: '',
description: '',
picture: 'jnj',
username: 'Tylor',
category: 'All',
createDate: new Date()
}
const CreateView = () => {
const [post, setPost] = useState(initialValues);
const history = useHistory();
const handleChange = (e) => {
setPost({...post, [e.target.name]:e.target.value});
}
const savePost = async() => {
try {
const {title, description, picture, username, category, createDate} = post;
console.log(post);
const res = await fetch('/create', {
method: "POST",
headers: {
"Content-Type":"application/json"
},
body: JSON.stringify({title, description, picture, username, category, createDate})
})
console.log(post);
console.log("res is "+ res);
if(res.status===200 )
{
window.alert("post created");
console.log(res);
}
}
catch(e){
console.log(`save post error ${e}`);
}
}
const classes = useStyles();
const url = "https://images.unsplash.com/photo-1543128639-4cb7e6eeef1b?ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8bGFwdG9wJTIwc2V0dXB8ZW58MHx8MHx8&ixlib=rb-1.2.1&w=1000&q=80";
return (
<>
<Box className={classes.container}>
<form method="POST">
<img src={url} alt="banner" className={classes.image}/>
<FormControl className={classes.form}>
<AddIcon fontSize="large" color="action" />
<InputBase placeholder="Title" className={classes.textfield} name="title" onChange={(e)=>handleChange(e)}/>
<Button variant="contained" color="primary" onClick={()=>savePost()}>Publish</Button>
</FormControl>
<TextareaAutosize aria-label="empty textarea" placeholder="Write here..." className={classes.textarea} name="description" onChange={(e)=>handleChange(e)}/>
</form>
</Box>
</>
)
}
export default CreateView;
I think problem is you checking status 200 , so your server returning status 200 in anyway as response . You have to check your server side , and check if is returning code 400 or anything else on failure .

React Native fetch API response not displaying

I am creating an app using expo. You can check the snack here
I am also giving the code here:
import React, {Component} from 'react';
import { ActivityIndicator, Text, View, StyleSheet, FlatList, Alert, TouchableOpacity } from 'react-native';
import {Avatar, Card, Button, Divider, ListItem, Image} from 'react-native-elements';
import Icon from 'react-native-vector-icons/FontAwesome';
import Constants from 'expo-constants';
import HTML from 'react-native-render-html';
import UserAvatar from 'react-native-user-avatar';
import { StackNavigator } from 'react-navigation';
import { createAppContainer} from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
class HomeScreen extends React.Component{
static navigationOptions =
{
title: '',
};
constructor(props){
super(props);
this.state = {
Loading : true,
data : []
}
}
fetchLeash(){
fetch('https://lishup.com/app/')
.then((response) => response.json())
.then((responseJson) => {
this.setState({ data: responseJson, Loading:false });
}).catch((error) => {
Alert.alert('error!');
});
}
fetchImage(getimg){
fetch('https://lishup.com/app/fetch-image.php', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
image: getimg
})
}).then((response) => response.json())
.then((responseJson) => {
return (<Text>responseJson.url</Text>);
}).catch((error) => {
Alert.alert('error');
});
}
componentDidMount(){
this.fetchLeash();
}
renderLeash = ({ item }) => (
<View>
<Card style={{ height:100, justifyContent: 'center', alignItems: 'center' }}>
<ListItem
leftAvatar={{
title: item.user,
source: { uri: item.userpic },
}}
title={item.user}
subtitle={item.time}
chevron
/>
<Divider style={{margin:5, backgroundColor:'white'}} />
<HTML html={item.text} />
{this.fetchImage(item.images)}
</Card>
</View>
)
render(){
if(this.state.Loading == true){
return(
<ActivityIndicator size="large" style={{marginTop:100}} color="#0000ff" />
);
}else{
return(
<View>
<FlatList style={{width:400}}
data={this.state.data}
renderItem={this.renderLeash} />
</View>
);
}
}
}
const styles = StyleSheet.create({
});
const RootStack = createStackNavigator(
{
Home: { screen: HomeScreen },
},
{
initialRouteName: 'Home',
}
);
export default createAppContainer(RootStack);
If you run the snack in your device, you will see that the posts(fetchLeash() function) is working fine. But the fetchImage() is returning nothing.
My fetch-image.php file is here:
<?php
// Importing DBConfig.php file.
include 'DB.php';
header('Content-Type: application/json');
// Creating connection.
$con = mysqli_connect($HostName,$HostUser,$HostPass,$DatabaseName);
// Getting the received JSON into $json variable.
$json = file_get_contents('php://input');
// decoding the received JSON and store into $obj variable.
$obj = json_decode($json,true);
// Populate User email from JSON $obj array and store into $email.
$image = $obj['image'];
if($image == "") {
$blank[] = array("url"=>"");
echo json_encode($blank);
}else{
//query to get image url with the code received
$Sql_Query = "SELECT * FROM `leash_img` WHERE `pid`= '".$image."' ";
// Executing SQL Query.
$check = mysqli_query($con,$Sql_Query);
if($check){
while($row=mysqli_fetch_assoc($check)){
$SuccessLoginMsg[] = array("url"=> $row['image']);
}
// Converting the message into JSON format.
$SuccessLoginJson = json_encode($SuccessLoginMsg);
echo $SuccessLoginJson;
}
}
?>
This returns like the following:
[{"url":"link here"}]
The PHP file is working fine. But the react native fetchImage() is not working.
I am totally new to react native. So forgive my problems. I am just out of my ideas. Please help me.
You can't asynchronously render UI from the render function, you need to fetch the data outside it in one of the lifecycle functions and conditionally render UI while it is being fetched.
Once the data has been fetched you should go ahead and fetch the image urls. Use Promise.all and map each response item to a fetch request. This will allow all image url fetches to resolve asynchronously and maintain index order.
fetchLeash() {
fetch('https://lishup.com/app/')
.then((response) => response.json())
.then((responseJson) => {
this.setState({ data: responseJson });
Promise.all(responseJson.map(({ images }) => this.fetchImage(images)))
.then((images) => {
this.setState({ imageUrls: images.map(url => ({ uri: url })) })
});
})
.catch((error) => {
Alert.alert('error!');
})
.finally(() => {
this.setState({ Loading: false });
});
}
The other important change is that the image response is an array of length 1, so need to access correctly.
fetchImage(image) {
return fetch('https://lishup.com/app/fetch-image.php', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ image }),
})
.then((response) => response.json())
.then((responseJson) => responseJson[0].url);
}
Now you can conditionally render an Image if the url at that index exists.
renderLeash = ({ item, index }) => (
<View>
<Card
style={{ height: 100, justifyContent: 'center', alignItems: 'center' }}>
<ListItem
leftAvatar={{
title: item.user,
source: { uri: item.userpic },
}}
title={item.user}
subtitle={item.time}
chevron
/>
<Divider style={{ margin: 5, backgroundColor: 'white' }} />
<HTML html={item.text} />
<Text>
{this.state.imageUrls[index] && this.state.imageUrls[index].uri}
</Text>
{this.state.imageUrls[index] && (
<Image
source={this.state.imageUrls[index]}
style={{ width: 100, height: 100 }}
PlaceholderContent={<ActivityIndicator />}
/>
)}
</Card>
</View>
);
Expo Snack
EDIT Allow display of all fetched image URLs. Instead of grabbing and returning just the first URL, return an array of URLs. Below I mapped the URLs to a new array before returning them, and these can be set directly in state now. Update the render function to use an additional guard (array length check) and render null if array doesn't exist. (Could also use another FlatList here if you wanted to)
fetchLeash() {
return fetch('https://lishup.com/app/')
.then((response) => response.json())
.then((responseJson) => {
this.setState({ data: responseJson });
Promise.all(
responseJson.map(({ images }) => this.fetchImage(images))
).then((imageUrls) => this.setState({ imageUrls }));
})
.catch((error) => {
Alert.alert('error!');
})
.finally(() => {
this.setState({ Loading: false });
});
}
fetchImage(image) {
return fetch('https://lishup.com/app/fetch-image.php', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ image }),
})
.then((response) => response.json())
.then((responseJson) =>
// Filter elements with empty string URLs, then app just the URL
responseJson.filter(({ url }) => url).map(({ url }) => url)
);
}
...
{this.state.imageUrls[index] && this.state.imageUrls[index].length
? this.state.imageUrls[index].map((uri) => (
<Image
source={{ uri }}
style={{ width: 100, height: 100 }}
PlaceholderContent={<ActivityIndicator />}
/>
))
: null}

How to fetch data from URL and then store it in AsyncStorage in React Native?

I'm trying to fetch data from URL and then store it in AsyncStorage in React Native.
This is screen where "magic" happens:
class CardsScreen extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
dataSource: null,
}
}
componentDidMount() {
return fetch(REQUEST_URL)
.then((response) => response.json())
.then((responseData) => {
this.setState({
isLoading: false,
dataSource: responseData,
});
})
.catch((error) => {
console.log(error)
});
}
render() {
if (netStatus) {
if (this.state.isLoading) {
return (
<View style={styles.container}>
<ActivityIndicator/>
</View>
)
} else {
let data = this.state.dataSource.map((val, key) => {
return <View key={key} style={styles.itemWrapper}>
<View style={styles.titleWrapper}>
<Text style={styles.content}>{val.type}</Text>
<Text style={styles.title}>{val.title}</Text>
<Text style={styles.content}>{val.date}</Text>
</View>
<View style={styles.imageWrapper}>
<Image
style={styles.image}
source={{uri: val.image}}
/>
</View>
<View style={styles.contentWrapper}>
<Text style={styles.content}>{val.adress}</Text>
<Text style={styles.content}>{val.text}</Text>
</View>
</View>
})
return (
<ScrollView contentContainerStyle={styles.containerScroll}>
{data}
</ScrollView>
);
}
} else {
return <View style={styles.contentWrapper}>
<Text style={styles.content}>Not connected!</Text>
</View>
}
}
};
This code prints data if device is connected to internet.
What I need to do is if device is conneted to internet, fetch data from URL and store (or overwrite) it in AsyncStorage, and then print data on screen. If device is not connect to the internet just print data from AsyncStorage.
This is example of .json I call from URL:
[
{
"type": "Party",
"title": "New party comming to town!",
"adress": "New Yrok",
"date": "20. 4. 2019.",
"image": "https:\/\/some-url.com\/some-image.jpg",
"text": [
"Some description"
],
"_id": "events_1"
}
]
I can't find any similar solution, so I would be greatfull if someone has tutorial that could help me with this.
EDIT (little more of explenation):
This is what I want to do:
If device is connected to the internet, update AsyncStorage with data from URL and then display that new data in AsyncStorage. If device is not connected to the internet, just display data that is AsyncStorage. And there are multiple "events", not just one like in the example.
export default class BankDetails extends Component {
constructor(props) {
super(props)
this.state = {
userToken: null,
userData: {
nameOfBank: '',
account_umber: '',
account_holder_ame: ''
}
}
}
async componentDidMount () {
try {
let value = await AsyncStorage.getItem('userData')
let userDetails = JSON.parse(value)
if (userDetails !== null) {
let userData= Object.assign({}, this.state.userData)
userData.nameOfBank = userDetails.nameOfBank
userData.account_umber = userDetails.account_umber
userData.account_holder_ame = userDetails.account_holder_ame
this.setState({
userToken: userDetails.token,
userData
})
}
} catch (error) {
console.log(error)
}
}
onBankChange = (nameOfBank) => {
this.setState({userData: {...this.state.userData, nameOfBank:nameOfBank}})
}
saveBankDetailsEdit = () => {
const { nameOfBank,account_umber, account_holder_ame }= this.state.userData
let {userToken} = this.state
var formData = new FormData()
formData.append('bank', nameOfBank)
formData.append('account_number', account_umber)
formData.append('account_title', account_holder_ame)
fetch('http://xxxx/update', {
method: 'POST',
headers: {
'X-API-KEY': '123456',
'Authorization': userToken
},
body: formData
}).then(function (response) {
console.log(response)
AsyncStorage.getItem('userData').then(
data => {
data = JSON.parse(data)
data.nameOfBank = nameOfBank
data.account_umber = account_umber
data.account_holder_ame = account_holder_ame
AsyncStorage.setItem('userData', JSON.stringify(data))
}
)
let data = JSON.parse(response._bodyText)
Alert.alert(data.message)
})
.catch((error) => {
console.log(error)
})
.done()
}
This is how I have done my job. Hope this helps.
You need to store your response like this
note one thing when you set value into AsyncStorage you need to store as string JSON.stringify() value into storage.
onSave = async () => {
try {
await AsyncStorage.setItem("key", JSON.stringify(responseData));
Alert.alert('Saved', 'Successful');
} catch (error) {
Alert.alert('Error', 'There was an error.')
}
}
and when you get value from AsyncStorage you need to JSON.parse()
onSave = async () => {
try {
const storedValue = await AsyncStorage.getItem("key");
this.setState({ storedValue: JSON.parse(storedValue) });
} catch (error) {
Alert.alert('Error', 'There was an error.')
}
}
hope it will help you

Trying to put API call and getting "Actions must be plain objects. Use custom middleware for async actions."

I am trying to make a login and logout pages using my API and Redux.
Currently I am having types: LOGIN, LOGIN_FAILED and LOGOUT.
In reducer I created a case for every type
This is how it looks like:
import React, { Component } from "react";
import {
LOGIN,
LOGIN_FAILED,
LOGOUT
} from '../types'
const defaultState = {
isLoggedIn: false,
UserName: '',
UserEmail: '',
UserPassword: ''
};
export default function reducer(state = defaultState, action) {
switch (action.type) {
case LOGIN:
return Object.assign({}, state, {
isLoggedIn: true,
UserName: action.UserName,
UserEmail: action.UserEmail,
UserPassword: action.UserPassword
});
case LOGOUT:
return Object.assign({}, state, {
isLoggedIn: false,
UserName: '',
UserEmail: '',
UserPassword: ''
});
case LOGIN_FAILED:
return {
UserName: '',
UserEmail: '',
UserPassword: '',
isLoggedIn: false
}
default:
return state;
}
And these are actions:
import {
LOGIN,
LOGIN_FAILED,
LOGOUT
} from '../types'
export const login = (UserName, UserEmail, UserPassword) => async (dispatch) => {
function onSuccess(success) {
dispatch({ type: LOGIN, payload: success })
return success
}
function onError(error) {
dispatch({ type: LOGIN_FAILED, error })
return error
}
try {
const { UserEmail } = this.state ;
const { UserName } = this.state ;
const { UserPassword } = this.state ;
const res = await fetch('https://lifestormweb.000webhostapp.com/User_Login.php', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: UserEmail,
password: UserPassword,
name: UserName
})
}).then((response) => response.json())
.then((responseJson) => {
// If server response message same as Data Matched
if(responseJson === 'Data Matched')
{
//Then open Profile activity and send user email to profile activity.
this.props.navigation.navigate("Profil");
}
else{
Alert.alert(responseJson);
}
})
const success = await res.json()
return onSuccess(success)
} catch (error) {
return onError(error)
}
};
export const logout = () => {
return {
type: 'LOGOUT'
};
};
Login.js page:
export class Login extends Component {
state = {
UserName: '',
UserEmail: '',
UserPassword: ''
}
userLogin (e) {
this.props.onLogin(this.state.UserName, this.state.UserEmail, this.state.UserPassword);
e.preventDefault();
}
render() {
return (
<View style={styles.container}>
<View style={styles.loginTextCont}>
<Text style={{fontSize: 36, fontFamily: "Futura" }}>
Willkommen zu</Text> <Text style={{fontSize: 36, fontFamily: "Futura", color:'#ff0000' }}>LifeStorm!</Text>
<View style={{width: 10, height: 5 }} />
</View>
<TextInput style={styles.inputBox}
autoCapitalize='none'
autoCorrect={false}
autoFocus={true}
keyboardType='email-address'
placeholder="Ihre Name"
placeholderTextColor = "#ffffff"
selectionColor="#ffffff"
value={this.state.UserName}
onChangeText={(text) => this.setState({ UserName: text })} />
<TextInput style={styles.inputBox}
autoCapitalize='none'
autoCorrect={false}
autoFocus={true}
keyboardType='email-address'
placeholder="Ihre E-Mail"
placeholderTextColor = "#ffffff"
selectionColor="#ffffff"
value={this.state.UserEmail}
onChangeText={(text) => this.setState({ UserEmail: text })} />
<TextInput style={styles.inputBox}
placeholder='Password'
autoCapitalize='none'
autoCorrect={false}
placeholder="Ihre Passwort"
placeholderTextColor = "#ffffff"
selectionColor="#ffffff"
secureTextEntry={true}
value={this.state.UserPassword}
onChangeText={(text) => this.setState({ UserPassword: text })} />
<TouchableOpacity
style={styles.button}
onPress={(e) => this.userLogin(e)}
>
<Text style={styles.buttonText}>Sich einloggen</Text>
</TouchableOpacity>
<View style={styles.signupTextCont}>
<Text style={styles.signupText}>
Haben Sie kein Konto?
</Text>
<TouchableOpacity onPress={()=>this.props.navigation.navigate("Register")}> <Text style={styles.signupButton}> Sich anmelden</Text></TouchableOpacity>
</View>
</View>
);
}
}
const mapStateToProps = (state, ownProps) => {
return {
isLoggedIn: state.auth.isLoggedIn,
};
}
const mapDispatchToProps = (dispatch) => {
return {
onLogin: (UserName, UserEmail, UserPassword) => { dispatch(login(UserName, UserEmail, UserPassword)); }
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Login);
Now every time when I try to log in I receive following error:
Actions must be plain objects. Use custom middleware for async actions
What am I missing?
I think your problem is returning your success/error objects instead of just dispatching. Can you try this and see if the problem goes:
function onSuccess(success) {
return dispatch({ type: LOGIN, payload: success })
// return success -- delete this
}
function onError(error) {
return dispatch({ type: LOGIN_FAILED, error })
// return error -- delete this
}