I have the following code which is not working to show an alert after my async function ends.
{
new BaseService().request(
serviceURL,
"POST",
headerParams,
bodyParams,
serverResponse => {
this.setState({ isLoading: true });
AuthenticationService.completeAuthentication(
serverResponse,
clientResponse => {
this.setState({ isLoading: false }); // THIS WORKS AND HIDES LOADER
alert("Authenticated Successfully!"); //THIS DOESN'T SHOW UP AN ALERT
},
error => {
alert(error);
}
);
}
)
}
Any leads?
Remember that not all browser functionalities will work in React Native, and that's the case for the alert API that you are using.
If you want a similar functionality, you should try with React Native's Alert component instead
Move the alert into the callback of setState
like bellow
clientResponse => {
this.setState({ isLoading: false },
() => alert("Authenticated Successfully!"));
},
Related
I have integrated react-native-iap for in app purchase.
Android Payment flow works properly(payment success, payment failed and user cancel payment).
But facing issue when purchase card is shown and I click outside the card, card is dismissed but not getting event inside RNIap.purchaseErrorListener .
Hence my state variable did not updated.
here is sample:
Listener code :
useEffect(() => {
initPurchase()
purchaseErrorSubscription = RNIap.purchaseErrorListener(
(error) => {
console.log('purchaseErrorListener INAPP>>>>', error);
if(error.code == "E_USER_CANCELLED") {
//for cancelled or refund sku
setSelectedPackage(null)
RNToasty.Show({
title: error.message,
});
} else if(error.code == "E_ITEM_UNAVAILABLE") {
//item not found
setSelectedPackage(null)
} else {
setSelectedPackage(null)
}
},
);
}, [])
Listener not called when I perform above action.
Can anyone help me to get this event?
Thanks in advance!!
you need to put this in a function, and in useEffect call this function
const checkCurrentPurchaseError = async () => {
purchaseErrorListener(async currentPurchaseError => {
if (currentPurchaseError) {
Here is your code...
}
});
};
useEffect(() => {
checkCurrentPurchaseError(currentPurchaseError);
}, []);
I'm building an android app using React-native and using PermissionsAndroid from react-native to get user permission.
import {PermissionsAndroid} from 'react-native'
Now i'm writing unit test and i need to verify the component behaviour based on the Permission.
hence i need to mock PermissionsAndroid.
Is there a way to do this?
jest.mock('react-native//Libraries/PermissionsAndroid/PermissionsAndroid', () => {
const PermissionsAndroid = jest.requireActual(
'react-native//Libraries/PermissionsAndroid/PermissionsAndroid',
);
console.log(PermissionsAndroid);
return {
...PermissionsAndroid,
check: jest.fn(() => new Promise(resolve => resolve(true))),
request: jest.fn(() => new Promise(resolve => resolve(true))),
};
});
This worked for me in 2022
jest.mock('react-
native//Libraries/PermissionsAndroid/PermissionsAndroid', () => {
return {
...jest.requireActual('react- native//Libraries/PermissionsAndroid/PermissionsAndroid'),
request: jest.fn(() => new Promise(resolve => resolve('granted')))
}
})
Because it is async you have to later on await it e.g. with react testing library const element = await findByText(...)
Simply mocking
jest.doMock('react-native', () => ({ PermissionsAndroid: {... did not work for me. Here is how I got it to work specifically mocking requestMultiple and check.
let fineLocationPermissionResult: String = PermissionsAndroid.RESULTS.GRANTED;
let courseLocationPermissionResult: String = PermissionsAndroid.RESULTS.GRANTED;
let fineLocationPermissionGranted = true;
let coarseLocationPermissionGranted = true;
const permissionsAndroidModule = jest.requireActual('react-native/Libraries/PermissionsAndroid/PermissionsAndroid.js');
jest.doMock('react-native/Libraries/PermissionsAndroid/PermissionsAndroid', () => ({
...permissionsAndroidModule,
requestMultiple: () => {
return {
[PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION]: fineLocationPermissionResult,
[PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION]: courseLocationPermissionResult,
};
},
check: () => {
return fineLocationPermissionGranted && coarseLocationPermissionGranted;
},
}));
I've included some of the variables I used in my tests to manipulate the results of the mock but essentially you need to mock the entire module path ('react-native/Libraries/PermissionsAndroid/PermissionsAndroid') and then include the rest of the module that you are not mocking via jest.requireActual.
Solution below:
jest.mock(
'react-native//Libraries/PermissionsAndroid/PermissionsAndroid',
() => ({
PermissionsAndroid: {
request: () => {
true;
},
check: () => {
true;
},
},
})
);
You can mock this from react-native directly, just like:
jest.doMock('react-native', () => ({
PermissionsAndroid: {
request: (permission: string) => {
//whatever you want
},
},
}))
Notice that you might see some issues with the components you are using for that unit test, i.e. it might show an error if you are using <View> from React Native and not mocking it. Given that case, you have to import <View> and then include it in your mock.
import { View } from 'react-native'
...
jest.doMock('react-native', () => ({
View,
PermissionsAndroid: {
request: (permission: string) => {
//whatever you want
},
},
}))
I am working on react native application and want to integrate the Phone masking feature like Uber do. I have choosen Twilio Phone Masking for this. I have used react-native-twilio-programmable-voice package.
I have integrated this using this link:: https://medium.com/#edzh1/create-a-twilio-voip-calls-in-a-react-native-app-35a729a9613d
I have done server setup successfully, using php. But getting error deviceNotReady error : "Registration failed". I have no idea what I am doing wrong here.
This is initial function I am calling here::
initTwilio = async () => {
const token = await this.getAuthToken();
if (Platform.OS === 'android') {
await this.getMicrophonePermission();
}
const success = await TwilioVoice.initWithToken(token);
if (success.initialized) {
TwilioVoice.addEventListener('deviceReady', () => {
this.setState({ twilioInited: true });
});
TwilioVoice.addEventListener('deviceNotReady', function (data) {
console.log('data', data) // getting error here
});
if (Platform.OS === 'ios') { //required for ios
TwilioVoice.configureCallKit({
appName: 'ReactNativeTwilioExampleApp',
});
}
}
};
getAuthToken = () => {
return fetch('https://myurl/accessToken.php', {
method: 'get',
})
.then(response => response.text())
.catch((error) => console.error(error));
}
Please help, and suggest me what I am doing wrong here.
I am building an integrated app with Android native and React native communicating with each other.
For sending data from Native to React native I tried to pass data by using initial props but it was not working and showing undefined. Then I tried to use DeviceEventEmitter which kind of worked but there was a slight problem.
EDITED :
Here's the code snippet:
class Details extends Component {
constructor(props){
super(props);
this.state={data: '', id: '278'}
}
componentDidMount(){
const eventEmitter = new NativeEventEmitter();
this.subscription = eventEmitter.addListener('customEventName',(e: Event)=>{
this.setState({id: e.key1});
console.warn(this.state.id);
});
const API_key = "APIkey"
console.warn(this.state.id);
const URL = "https://api.themoviedb.org/3/movie/" + this.state.id + "?api_key=" + API_key + "&language=en-USs"
return fetch(URL, {
method: 'GET'
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({
data: responseJson,
},
function(){
});
})
.catch((error) =>{
console.error(error);
});
}
componentWillUnmount(){
this.subscription.remove();
}
render() {
return(
/*something*/
);
}
}
The value of id is being successfully sent from native component to React native component.
Problem: The console.warn() inside addlistener() is showing after the console.warn() which is below declaring the API_key, and hence the this.state.id is not being updated.
Please any help will be appreciated.
your event register should be something as mentioned below, as you are registering the event so the scope of this should be event handler specific so if you want to access the parent scope you need to use the arrow function like mentioned below.
DeviceEventEmitter.addListener('customEventName',(e: Event)=> {
this.id = e.key1
console.warn("inside event emitter", this.id);
});
If you are successfully getting the event then I think this is just a React problem.
It looks like you want to fetch after you have successfully got the ID, but you're trying to fetch straight away in componentDidMount.
As fetch is a side effect you probably want to use componentDidUpdate like so:
import { NativeEventEmitter } from 'react-native'
constructor(props){
super(props);
this.state={
data: '',
id: ''
}
}
componentDidMount(){
const eventEmitter = new NativeEventEmitter();
this.subscription = eventEmitter.addListener('customEventName',(e: Event)=>{
this.setState({id: e.key1});
console.warn(this.state.id);
});
}
componentDidUpdate() {
const { id } = this.state
if (id) {
const URL = "https://api.themoviedb.org/3/movie/" + this.state.id + "?api_key=" + API_key + "&language=en-USs"
return fetch(URL, {
method: 'GET'
})
// ... etc
}
}
// ...etc
Note that id starts out as empty.
This my code(used to fetch data).
loadApi() {
this.setState({isListLoaded : true})
return fetch('http://www.androidbegin.com/tutorial/jsonparsetutorial.txt')
.then((response) => response.json())
.then((responseJson) => {
this.setState({listView : responseJson.worldpopulation})
this.setState({isListLoaded : false})
ToastAndroid.show('A pikachu appeared nearby !', ToastAndroid.SHORT);
})
.catch((error) => {
console.error(error);
});
}
How can i set a timeout to this specific syntax ?.Please share the code part if you have any.
There is no standard way till now according to this github thread.
However there is one solution, use whatwg-fetch-timeout
sample code :
return fetch('/path', {timeout: 500}).then(function() {
// successful fetch
}).catch(function(error) {
// network request failed / timeout
})