React native unhandled promise rejection p0 - react-native

Hello i get the above error when i run my project what am i doing wrong?
import * as WebBrowser from 'expo-web-browser';
import React , {Component} from 'react';
import {PermissionsAndroid} from 'react-native';
import {
Image,
Platform,
ScrollView,
StyleSheet,
Text,
Button,
TouchableOpacity,
View,
Switch
} from 'react-native';
import { MonoText } from '../components/StyledText';
import {Linking , SMS }from 'expo';
import * as Permissions from 'expo-permissions'
class Sendsms extends Component {
state = {switch1Value: false}
toggleSwitch1 = (value) => {
this.setState({switch1Value: value});
console.log('Switch 1 is: ' + value);
}
askSMSPermissionsAsync = async () => {
await Permissions.askAsync(Permissions.SMS);
};
HandlePress = () =>{
console.log('try to send sms');
}
render(){
return(
<View>
<Text>{this.state.switch1Value ? 'Switch is ON' : 'Switch is OFF'}</Text>
<Switch onValueChange = {this.toggleSwitch1.bind(this)} value = {this.state.switch1Value}/>
<Button title="sendSMS" onPress={this.askSMSPermissionsAsync} />
</View>
)
}
}
I tried rebulding project and deleting the build folder with no luck
I also tried to copy the code in some other project still same error
export default Sendsms;

You need to wrap your await call in a try/catch to handle the rejected promise. I'm not sure why it's getting rejected but you could console.log to find out by doing:
askSMSPermissionsAsync = async () => {
try {
await Permissions.askAsync(Permissions.SMS);
} catch(e) {
console.log(e);
}
};
Remember that await is just syntactic sugar for a promise.

await Permissions.askAsync(Permissions.SMS); results into a Promise which might be rejected. When using promises, always use a try {} catch(e) {} to catch any rejections.
Check the logging for more info about the rejection.
So:
askSMSPermissionsAsync = async () => {
try {
await Permissions.askAsync(Permissions.SMS);
} catch (e) {
console.error(e);
}
};

Related

How to play audio from server use expo-av in react-native

I try to play video from server. This is my code:
import React, {useState, useEffect} from 'react';
import { Button } from 'react-native';
import { Audio } from 'expo-av';
export default function App() {
const [audioStatus, setAudioStatus] = useState(false)
const [sound, setSound] = useState(new Audio.Sound());
useEffect(()=>{
(async () => {
console.log('status', audioStatus)
if (audioStatus) {
await sound.loadAsync('https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3')
try {
await sound.playAsync()
} catch (e) {
console.log(e)
}
}else {
await sound.stopAsync()
await sound.unloadAsync()
}
})()
},[audioStatus])
return (
<Button color={audioStatus ? 'red' : 'green'} title={'play'} onPress={()=>setAudioStatus(!audioStatus)} />
);
}
And I get error:
LOG status false
WARN Possible Unhandled Promise Rejection (id: 15):
Error: Cannot complete operation because sound is not loaded.
http://192.168.100.60:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:100133:28
generatorResume#[native code]
asyncGeneratorStep#http://192.168.100.60:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:20982:26
It looks like your post is mostly code; please add some more details.It looks like your post is mostly code; please add some more details.

Context API dispatch not called with onEffect while using expo-splash-screen

When I am trying to use the dispatch function recieved with the useContext hook I cannot get the change the content of the data inside the context. It looks like as if the call wasn't even made, when I try to log something inside the conext's reducer it doesn't react. When I try to call it from other components, it works just fine.
Sorry if it's not clean enough, I'm not too used to ask around here, if there's anything else to clarify please tell me, and I'll add the necessary info, I just don't know at the moment what could help.
import { QueryClient, QueryClientProvider } from "react-query";
import LoginPage from "./src/pages/LoginPage";
import { UserDataContext, UserDataProvider } from "./src/contexts/UserData";
import { useState } from "react";
import AsyncStorage from "#react-native-async-storage/async-storage";
import { useContext } from "react";
import * as SplashScreen from "expo-splash-screen";
import { useEffect } from "react";
import { useCallback } from "react";
import { UserData } from "./src/interfaces";
SplashScreen.preventAutoHideAsync();
const queryClient = new QueryClient();
export default function App() {
const [appReady, setAppReady] = useState<boolean>(false);
const { loggedInUser, dispatch } = useContext(UserDataContext);
useEffect(() => {
async function prepare() {
AsyncStorage.getItem("userData")
.then((result) => {
if (result !== null) {
console.log(loggedInUser);
const resultUser: UserData = JSON.parse(result);
dispatch({
type: "SET_LOGGED_IN_USER",
payload: resultUser,
});
new Promise((resolve) => setTimeout(resolve, 2000));
}
})
.catch((e) => console.log(e))
.finally(() => setAppReady(true));
}
if (!appReady) {
prepare();
}
}, []);
const onLayoutRootView = useCallback(async () => {
if (appReady) {
await SplashScreen.hideAsync();
}
}, [appReady]);
if (!appReady) {
return null;
}
return (
<>
<UserDataProvider>
<QueryClientProvider client={queryClient}>
<LoginPage onLayout={onLayoutRootView} />
</QueryClientProvider>
</UserDataProvider>
</>
);
}
I'm thinking I use the context hook too early on, when I check the type of the dispatch function here it says it's [Function dispatch], and where it works it's [Function bound dispatchReducerAction].
I think the problem might come from me trying to call useContext before the contextprovider could render, but even when I put the block with using the dispatch action in the onLayoutRootView part, it didn't work.

undefined is not an object (evaluating 'userInfo._name') help me

I'm asking you this question because an error occurred again.
We're now receiving data through axios and storing that data through useState().
So if you create it on the screen and render it right away, you can see the data, but if you go to the previous page and go back in, an error occurs.
Please let me know how to solve it.
my Error
TypeError: undefined is not an object (evaluating 'userInfo._name')
my Code
import React, { useState, useEffect } from "react";
import { withNavigation } from "react-navigation";
import { Text, View, StyleSheet, SafeAreaView, Image } from "react-native";
import {
widthPercentageToDP as wp,
heightPercentageToDP as hp,
} from "react-native-responsive-screen";
import axios from "axios";
const MyPage = ({ navigation, info }) => {
const [userInfo, setUserInfo] = useState();
const getData = async () => {
try {
axios
.get(
"http://everyweardev-env.eba-azpdvh2m.ap-northeast-2.elasticbeanstalk.com/api/v1/user"
)
.then((res) => res)
.then((data) => {
setUserInfo(data.data.data.result);
})
.catch((err) => console.log(err));
} catch (error) {}
};
useEffect(() => {
const unsubscribe = navigation.addListener("focus", () => {
getData();
});
return unsubscribe;
}, [navigation]);
return (
<View>
{/* <Image source={require("../../images/profile.png")} /> */}
<Text>{userInfo._name}</Text>
<Text>{userInfo._mail}</Text>
</View>
);
};
export default withNavigation(MyPage);
The problem is happening in the initial render where the userInfo object is null.
Do something like below, where you access the property only when there is a value for userInfo
<Text>{userInfo?._name}</Text>
<Text>{userInfo?._mail}</Text>

Expo Audio.Recording Cannot read property 'uri' of undefined

I'm trying to start a new recording in Expo react native but for some odd reason the app crashes.
The code i written is pretty much copy paste from the official expo docs.
import React, { useState, useEffect } from 'react';
import { Audio } from 'expo-av';
import PitchFinder from "pitchfinder";
import { StyleSheet, Text, View, Button } from 'react-native';
const Tuner = () => {
const pitchFinder = new PitchFinder.YIN();
const start = async () => {
const recording = new Audio.Recording();
console.log(recording)
await recording.prepareToRecordAsync(Audio.RECORDING_OPTIONS_PRESET_HIGH_QUALITY);
await recording.startAsync();
const audio_stream = recording.getURI();
console.log(audio_stream);
await recording.stopAndUnloadAsync();
}
return (
<View>
<Button title="Start recording" onPress={() => start()} />
</View>
)
};
export default Tuner;
The app crashes at await recording.prepareToRecordAsync(Audio.RECORDING_OPTIONS_PRESET_HIGH_QUALITY);
with the error
Unhandled Rejection (TypeError): Cannot read property 'uri' of undefined
please check Expo documentation again
check permission
https://docs.expo.io/versions/latest/sdk/audio/
try with
const recording = new Audio.Recording();
try {
await recording.prepareToRecordAsync(Audio.RECORDING_OPTIONS_PRESET_HIGH_QUALITY);
await recording.startAsync();
// You are now recording!
} catch (error) {
// An error occurred!
}

useEffect returns unhandled promise

I have been for several hours trying to get an API to be called in ReactNative useEffect hook. Sometimes when I restart my app the value is resolved. But most of the time, I have an Unhandled promise rejection. I googled and tried various methods. I tried using .then etc.. I just can't figure it out.
import React, { useState, useContext, useEffect } from 'react';
import { View, Text, StyleSheet, TouchableOpacity, FlatList } from 'react-native';
import { EvilIcons } from '#expo/vector-icons';
import jsonServer from '../api/jsonServer';
const ShowScreen = ({ navigation }) => {
const id = navigation.getParam('id');
const [post, setPost] = useState([]);
const getBlog = async () => {
const result = await jsonServer.get(`http://0.0.0.0/blog/docroot/jsonapi/node/article/${id}`);
return result;
}
useEffect(() => {
async function setToState() {
const val = await getBlog();
setPost(val);
}
setToState();
},[]);
return (
<View>
<Text>Here { console.log(post) }</Text>
</View>
);
};
ShowScreen.navigationOptions = ({ navigation }) => {
return {
headerRight: (
<TouchableOpacity
onPress={() =>
navigation.navigate('Edit', { id: navigation.getParam('id')
})}
>
<EvilIcons name="pencil" size={35} />
</TouchableOpacity>
)
};
};
const styles = StyleSheet.create({});
export default ShowScreen;
What you could do is something like this:
....
....
const [post, setPost] = useState([]);
const [isMounted, setIsMounted] = useState(false);
const getBlog = async () => {
const result = await jsonServer.get(`http://0.0.0.0/blog/docroot/jsonapi/node/article/${id}`);
return result;
}
useEffect(() => {
setIsMounted(true)
async function setToState() {
// using try catch I'm handling any type of rejection from promises. All errors will move to catch block.
try{
const val = await getBlog();
// checking if component is still mounted. If mounted then setting a value. We shouldn't update state on an unmounted component.
if(isMounted){
setPost(val);
}
} catch(err){
console.log("Error", err)
}
}
setToState();
return () => {
// Setting is mounted to false as the component is unmounted.
setIsMounted(false)
}
},[]);
I believe this will solve your Unhandled promise rejection error. Please try if it still doesn't solve the issue will create the same in Sanck.
I think my issue was not just promise, the issue is also seems to be me not handling undefined/null in the state. The below code is working for me.
import React, { useState, useContext, useEffect } from 'react';
import { View, Text, StyleSheet, TouchableOpacity, FlatList } from 'react-native';
import { EvilIcons } from '#expo/vector-icons';
import jsonServer from '../api/jsonServer';
const ShowScreen = ({ navigation }) => {
const id = navigation.getParam('id');
const [post, setPost] = useState([]);
const getBlog = async () => {
const result = await jsonServer.get(`http://hello.com/jsonapi/node/article/${id}`).then(
res => {
setPost(res)
return res;
}, err => {
console.log(err);
});
}
useEffect(() => {
setPost(getBlog());
},[]);
return (
<View>
<Text>{ post.data ? post.data.data.id : "" }</Text>
</View>
);
};
export default ShowScreen;
Note: I am setting the state in useEffect as well as in the request. I am yet to check if I can just do it once.