React Native app closing after Razorpay sucessCallBack() - react-native

The entire payment is done properly. Here is the code:
'''
const that = this;
function makePayment(){
var options = {
description: 'Bank payment',
currency: 'INR',
key: 'xxx',
amount: that.state.amount_razorpay,
name: 'xyz',
order_id: that.state.id,
prefill: {
email: 'xxx#gmail.con',
contact: '123',
name: 'XYZ'
},
theme: {color: '#53a20e'}
}
RazorpayCheckout.open(options,razr_successCallback,razr_errorCallback)
}
function razr_successCallback(data){
console.log('success',data.razorpay_payment_id);
that.setState({razr_Status:"SUCCESS"});
that.setState({razr_txnId:data.razorpay_payment_id});
// that.props.navigation.navigate('Secured');
}
function razr_errorCallback(data){
console.log('failure',data);
}
'''
The console at razr_successCallback() is giving proper result {"razorpay_payment_id": "pay_Eby2FPTakKuSrz"} but the app is exiting immediately without navigation back to the payment page. I even tried that.props.navigation.navigate('Secured') but still the payment page is not redirected. What is the problem?
Edit 1 :
'''
RazorpayCheckout.open(options)
.then(async data =>
await razr_successCallback(data);
})
.catch(error => {
console.log("payment error", error);
});
async function razr_successCallback(data){
console.log(data);
that.props.navigation.goBack();
}
'''
Still facing same problem

This returns a promise, try it this way :
RazorpayCheckout.open(options)
.then(data => {
// handle success
razr_successCallback(data);
})
.catch(error => {
console.log("payment error", error);
});
in My Case :
const razorpayOpenModal = (razorpay_id, currency) => {
let options = {
description: "Credits towards consultation",
image: images.logo,
currency: currency,
order_id: razorpay_id,
key: RAZOPAY_KEY,
amount: totalAmount * 100,
external: {
wallets: ["paytm"]
},
name: "MyApp.jo",
prefill: {
email: userFromCtxt && userFromCtxt.email,
contact: userFromCtxt && userFromCtxt.phone,
name: userFromCtxt
? userFromCtxt.first_name + " " + userFromCtxt.last_name
: ""
},
theme: { color: color.primaryHeaderColor }
};
RazorpayCheckout.open(options)
.then(async data => {
setPaymentId(data.razorpay_payment_id);
await setShowModel(true);
})
.catch(error => {
console.log("payment error", error)
});
};
and then on model :
<MessageModal
button={true}
primaryMessage={primaryText}
secondaryMessage={secondaryText}
visible={modalVisible}
transactionResp={transactionResp}
closeModal={async () => {
setModalVisible(false);
await props.navigation.navigate("Home");
}}
buttonText={"Continue"}
image={transactionResp ? images.success : null}
onPressButton={async () => {
setModalVisible(false);
await props.navigation.navigate("Home");
}}
/>

Related

Await is only allowed within async functions error react native

I am new to react native and trying to save user obejct in application storage using await AsyncStorage.setItem('user', res[1].data); However I am getting error as
handleLogin = async() => {
NetInfo.fetch().then(state => {
if (state.isConnected) {
const {navigate} = this.props.navigation;
const data = {
email: this.state.userName,
password: this.state.password
};
fetch(`${DOMAIN_URL}/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
})
.then((response) => {
const statusCode = response.status.toString();
const data = response.json();
return Promise.all([statusCode, data]);
})
.then((res) => {
if (res[0] == 200) {
await AsyncStorage.setItem('user', res[1].data);
navigate('Home');
}else{
Alert.alert(
res[1].message
);
}
})
.catch((error) => {
console.error(error);
});
}
else {
Alert.alert(
"No Internet!",
"Needs to connect to the internet in order to work. Please connect tablet to wifi and try again.",
[
{
text: "OK",
onPress: () => { }
}
]
);
};
})
};
I have made the handleLogin async but it doesn't solve the error. What is the correct way to store user obejct?
It is recommended that you use react-native-easy-app , through which you can access any data in AsyncStorage synchronously.
Sample_Hooks
StorageController
navigateToHome = async (user) => {
const { navigate } = this.props.navigation;
await AsyncStorage.setItem('user', user);
navigate('Home');
}
handleLogin = async() => {
NetInfo.fetch().then(state => {
if (state.isConnected) {
const data = {
email: this.state.userName,
password: this.state.password
};
fetch(`${DOMAIN_URL}/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
})
.then((response) => {
const statusCode = response.status.toString();
const data = response.json();
return Promise.all([statusCode, data]);
})
.then((res) => {
if (res[0] == 200) {
navigateToHome(res[1].data);
}else{
Alert.alert(
res[1].message
);
}
})
.catch((error) => {
console.error(error);
});
}
else {
Alert.alert(
"No Internet!",
"Needs to connect to the internet in order to work. Please connect tablet to wifi and try again.",
[
{
text: "OK",
onPress: () => { }
}
]
);
};
})
};

TypeError: this.props.navigation.getParam is not a function while passing parameter react native

I am using navigation version 5 and there are two screen home and search screen, i want to copy value search screen to home screen getting error TypeError: props.navigation.getParam is not a function.
Search Screen
async savechange() {
this.props.navigation.navigate('HomeScreen', { city: this.state.text })
await AsyncStorage.setItem("cityname", this.state.text)
}
async clicklist(name) {
this.setState({ text: name })
await AsyncStorage.setItem("cityname", this.state.text)
this.props.navigation.navigate('HomeScreen', { city: this.state.text })
}
Home Screen
async getWeather() {
// cityname = "london"
cityname = this.props.navigation.getparam('cityname','london')
console.log("CityName ->>" + cityname)
KeyID = '...'
fetch(`http://api.openweathermap.org/data/2.5/weather?q=${cityname}&units=metric&APPID=${KeyID}`)
.then(result => result.json())
.then(data => {
// console.log(data)
this.setState({
info: {
name: data.name,
temp: data.main.temp,
country: data.sys.country,
humidity: data.main.humidity,
description: data.weather[0].description,
icon: data.weather[0].icon
}
})
}).catch(err => {
Alert.alert("Error" + err.message + "Please connect to internet", [{ text: "Ok" }])
})
}
If you are using react-navigation V5 use:
props.route.params
For example:
props.navigation.navigate("ScreenB", {title: "Hello World"});
_________________________________________________________________
export default function ScreenB(props){
useEffect(() => {
setTitle(props.route.params.title);
},[])
...
}

react native async getting data when running app first time

I have two components, in first components storing data in asyncstorage, in second component display data, when install app and save data does not get data from asyncstorage, when open app second time data are displayed.
storeData = async (item, messave, messrem) => {
const checkarary = this.state.favorite;
if(checkarary.some(e => e.name === item.name)) {
const value = this.state.favorite;
const position = value.filter((lists) => lists.id !== item.id);
this.setState({
favorite: position
}, () => {
try {
AsyncStorage.setItem('favoriti', JSON.stringify(this.state.favorite), () => {
Toast.show({
text: messrem,
buttonText: "Okay",
duration: 3000,
type: "danger"
});
});
} catch (error) {
}
});
} else {
this.setState({
favorite: [...this.state.favorite, item]
}, () => {
try {
AsyncStorage.setItem('favoriti', JSON.stringify(this.state.favorite), () => {
// AsyncStorage.getItem('favoriti', (err, result) => {
// console.log(result);
// });
Toast.show({
text: messave,
buttonText: "Okay",
duration: 3000,
type: "success"
});
});
} catch (error) {
}
});
}
};
Getting data in second component
_retrieveData = async () => {
try {
AsyncStorage.getItem('favoriti').then((value) => {
const parsed = JSON.parse(value);
this.setState({ favorite: parsed })
})
} catch (error) {
}
};
componentDidMount() {
this._retrieveData();
setTimeout(() => {
this.setState({
loading: false,
})
}, 2000)
};
componentDidUpdate() {
this._retrieveData();
};
How fix this issue, is there some solution. Can I set Item and reload app when install app or somthing else.
Use this
componentWillMount() {
this._retrieveData();
setTimeout(() => {
this.setState({
loading: false,
})
}, 2000)
};
instead of
componentDidMount() {
this._retrieveData();
setTimeout(() => {
this.setState({
loading: false,
})
}, 2000)
};
As componentWillMount is called after constructor is called for class and componentDidMount is called after screen is once rendered.

upload mp4 with expo in react native problem

I'm new in react native and this might be a silly question, but when I'm trying to upload .mp4 with react native using expo in my backend server side (laravel) I receive a jpg/jpeg file which is weird because with the same code when I try to upload .mov file it works as expected without any problem.
is there anything I've done wrong?
p.s: I've already tried to fetch method and axios but I get the same result with both.
here's my code:
postForm = () => {
var body = new FormData();
body.append("title", this.state.text);
body.append("description", this.state.description);
body.append("category_id", this.state.category_id);
body.append("type", this.state.type);
body.append('media_path', {
uri: this.state.photos.photos[0].file,
name: `media.mp4`,
type: this.state.format
});
this.state.photos.photos.map((item, index) => {
console.log("addable item is", index, item.file);
//skip first photo to media_path
if (index == 0) {
console.log("avalin index: ", item.file)
return
}
else {
file = item.file.toLowerCase();
console.log("full name is", file);
let addable = {
uri: item.file,
name: `addables`,
type: this.state.format
}
body.append("addables[]", addable)
}
})
console.log("final body: ", body);
this.setState({
uploading: true,
}, function () {
let apiUrl = `${config.BASE_URL}api/products`;
console.log(apiUrl);
axios({
method: 'POST',
url: apiUrl,
data: body,
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data',
"authorization": this.state.token
}
})
.then((response) => {
//handle success
console.log("success response: ", response);
if (response.data.status == true) {
this.setState({
uploading: false
}, function () {
this.props.navigation.push('profile');
})
}
else {
this.setState({
uploading: false
}, function () {
this.showToast("unsuccessful operation.", "danger", 3000);
})
}
})
.catch(function (response) {
//handle error
console.log(response);
alert("response)
});
})
}
and this is what laravel logs tels me:
array (
'title' => 'test',
'description' => 'test',
'category_id' => '3',
'type' => 'video',
'media_path' =>
Illuminate\Http\UploadedFile::__set_state(array(
'test' => false,
'originalName' => 'media.mp4',
'mimeType' => 'image/jpeg',
'error' => 0,
'hashName' => NULL,
)),
)

can't set response from api to messages array of GiftedChat

I am new to react native. I am currently developing a messaging app.
I have used npm-giftedChat for UI & functionalities. The problem is I need to get the response from api & set it to the messages array of giftedchat. I receive data from API and while I set it to messages array it loops over data and renders only the last data in that array.
Any help would be appreciated.I have added my code here
Please find where I am going wrong?
componentWillMount() {
var arrMsg = [];
var data = params.data
for(let i = 0; i < data.Replies.length ; i++){
var obj = {
_id: data.To._id,
text: data.Replies[i].Reply,
createdAt: data.Replies[i].CreatedDate,
user: {
_id: data.From._id,
name: 'React Native',
avatar: data.From.Profile.DisplayPicture
},
image: '',
}
arrMsg.push(obj)
}
this.setState({messages: arrMsg})
}
Sample output
My self also facing same issues..
setting is very important in gifted chat..
so try to use following in ur code,i have edited same like your code.if any queries let me know thanks.
for (let i = 0; i < data.Replies.length; i++) {
console.log(data.Replies[i].CreatedDate);
debugger
var id = data.From._id
if (data.To.id == UserID) {
id = this.state.userID
}
const obj = {
_id: Math.round(Math.random() * 1000000),
text: data.Replies[i].Reply,
createdAt: data.Replies[i].CreatedDate,
user: {
_id: id,
name: 'React Native',
avatar: data.From.Profile.DisplayPicture
},
image: '',
}
arrMsg.push(obj);
};
this.setState((previousState) => {
return {
messages: GiftedChat.append(previousState.messages, arrMsg)
};
});
I wrote a gist here on how to add a web socket listening to a rails channel to a react native chat screen + Gifted Chat
// chat.js
import React, { Component } from 'react';
import {
Text,
View,
StyleSheet,
TouchableHighlight,
Dimensions,
AppState,
AsyncStorage,
Alert
} from 'react-native';
import {
GiftedChat,
Actions,
Bubble,
SystemMessage
} from 'react-native-gifted-chat';
import axios from 'axios';
import ActionCable from 'react-native-actioncable';
import { yourRootUrl, websocketUrl } from '../config/constants';
class Chat extends Component {
state = {
messages: [],
client: '',
accessToken: '',
expiry: '',
uid: '',
userId: ''
}
componentDidMount() {
AsyncStorage.multiGet(
['client', 'expiry',
'access_token', 'uid',
'account_balance', 'userId'
]
)
.then((result) => {
this.setState({
client: result[0][1],
expiry: result[1][1],
accessToken: result[2][1],
uid: result[3][1],
userId: result[5][1]
});
})
.then(() => {
this.getPreviousMessages();
})
.then(() => {
this.createSocket();
})
.catch(() => {
//error logic
});
}
getPreviousMessages() {
//when we open the chat page we should load previous messages
const { chatId } = this.props.navigation.state.params;
const { client, accessToken, uid, userId } = this.state;
const url = yourRootUrl + '/chats/' + chatId;
const headers = {
'access-token': accessToken,
client,
expiry,
uid
};
axios.get(url, { headers })
.then((response) => {
/*
lets construct our messages to be in
same format as expected by GiftedChat
*/
const allMessages = [];
response.data.included.forEach((x) => {
if (x.attributes.system) {
const sysMessage = {
_id: x.id,
text: x.attributes['message-text'],
createdAt: new Date(x.attributes['created-at']),
system: true
};
allMessages.push(sysMessage);
} else {
const userMessage = {
_id: x.id,
text: x.attributes['message-text'],
createdAt: new Date(x.attributes['created-at']),
user: {
_id: x.attributes['sender-id'],
avatar: x.attributes['sender-avatar'],
},
image: x.attributes.image,
};
allMessages.push(userMessage);
}
});
if (allMessages.length === response.data.included.length) {
//lets sort messages according to date created
const sortAllMessages = allMessages.sort((a, b) =>
b.createdAt - a.createdAt
);
this.setState((previousState) => {
return {
messages: GiftedChat.append(previousState.messages, sortAllMessages)
};
});
}
})
}
createSocket() {
//assuming you have set up your chatchannel in your rails backend
const { client, accessToken, uid, userId } = this.state;
const { chatId } = this.props.navigation.state.params; //using react-navigation
const WEBSOCKET_HOST = websocketUrl +
'access-token=' + accessToken + '&client=' +
client + '&uid=' + uid;
const cable = ActionCable.createConsumer(WEBSOCKET_HOST);
this.channel = cable.subscriptions.create(
{
channel: 'ChatChannel',
id: chatId
}, {
received: (data) => {
console.log('Received Data:', data);
if ((data.message.sender_id !== parseInt(userId))
|| (data.message.image !== null)) {
//ensuring you do not pick up your own messages
if (data.message.system === true) {
const sysMessage = {
_id: data.message.id,
text: data.message.message_text,
createdAt: new Date(data.message.created_at),
system: true
};
this.setState((previousState) => {
return {
messages: GiftedChat.append(previousState.messages, sysMessage)
};
});
} else {
const userMessage = {
_id: data.message.id,
text: data.message.message_text,
createdAt: new Date(data.message.created_at),
user: {
_id: data.message.sender_id,
avatar: data.message.sender_avatar,
},
image: data.message.image,
};
this.setState((previousState) => {
return {
messages: GiftedChat.append(previousState.messages, userMessage)
};
});
}
}
},
connected: () => {
console.log(`Connected ${chatId}`);
},
disconnected: () => {
console.warn(`${chatId} was disconnected.`);
},
rejected: () => {
console.warn('connection rejected');
},
});
}
onSend(messages = []) {
const { chatId } = this.props.navigation.state.params;
const { client, accessToken, uid, userId } = this.state;
this.setState((previousState) => {
return {
messages: GiftedChat.append(previousState.messages, messages)
};
});
messages.forEach((x) => {
const url = yourRootUrl + '/messages';
const headers = {
'access-token': accessToken,
client,
expiry,
uid
};
const data = {
chat_id: chatId,
sender_id: userId,
sender_name: name,
message_text: x.text,
image: x.image
};
/*
send the message to your rails app backend
hopefully you have a callback in your model like
after_create :broadcast_message
then broadcast to the chat channel from your rails backend
*/
axios.post(url, data, { headers })
.then(response => console.log(response));
});
}
renderBubble(props) {
return (
<Bubble
{...props}
wrapperStyle={{
left: {
backgroundColor: '#f9f9f9',
}
}}
/>
);
}
renderSystemMessage(props) {
return (
<SystemMessage
{...props}
containerStyle={{
marginBottom: 15,
}}
textStyle={{
fontSize: 14,
textAlign: 'center'
}}
/>
);
}
render() {
return (
<GiftedChat
messages={this.state.messages}
onSend={message => this.onSend(message)}
user={{
_id: parseInt(userId)
}}
renderBubble={this.renderBubble}
renderSystemMessage={this.renderSystemMessage}
/>
);
}
}