I'm pretty new to react native and need some help reg. the possiblity to read an image from a file (like an image). I'm using the expo filesystem library with the following code:
const uploadImages = (file) => {
let data = null;
try {
data = await FileSystem.readAsStringAsync(file);
console.log(data)
} catch (err) {
console.log(err)
}
The issue I have is that I get: 'await' is only allowed within async functions
How can I call this function to wait until the data is loaded into the data variable ?
FileSystem.readAsStringAsync(...) returns Promise.
You can use Promise api like .then() and .catch():
const uploadImages = (file) => {
FileSystem.readAsStringAsync(file)
.then(data => {
// Do something with your data in this block
console.log(data);
})
.catch(err => {
console.log(err.message)
})
}
Related
I am currently having a problem trying to sync or replicate the data from PouchDB to CouchDB. Whenever I try to sync or replicate I always get this error.
Cannot read properties of undefined (reading 'from').
Here is my code:
function openDB() {
return new PouchDB('cows.db', { adapter: 'react-native-sqlite' });
}
function openRemoteDB() {
return new PouchDB('http://admin:asdasd#127.0.0.1:5984/cows');
}
const runPouchDB = async () => {
const db = openDB();
console.log('db info:', await db.info());
const remotedb = openRemoteDB();
console.log('remote db info:', await remotedb.info());
db.replicate.to(remotedb, {})
.on('complete', async () => {
console.log('done!');
})
.on('error', function (err) {
console.error('failed to replicate:', err.message, err.stack);
});
db.sync(remotedb).on('complete', function () {
console.log('done');
// yay, we're in sync!
}).on('error', function (err) {
console.log('error', err);
// boo, we hit an error!
});
}
React.useEffect(() => {
runPouchDB().then(() => console.log('connected'));
}, [])
both approach always return an error. Not sure if it is a package issue or something I did wrong.
UPDATE:
Based on the example it is looking for global.base64FromArrayBuffer but base64FromArrayBuffer does not exist in my global context.
https://github.com/craftzdog/pouchdb-react-native/blob/138f3d6385238e5cf278366d0fb3d0434abbdced/example/src/App.js#L71
Not sure how to add since since I already added the shim which I though would fix the issue.
import { shim as shimBase64 } from 'react-native-quick-base64';
shimBase64();
I tried using redux to save token the one I get from api in react native ..its working now.
First one is for settoken and other one is for gettoken.
enter image description here
export const verifyOTP = (formValues, actions) => {
return async (dispatch) => {
dispatch(startSubmitting());
const url = `/validate-otp`;
var formdata = new FormData();
formdata.append("mobile", formValues.mobile);
formdata.append("otp", formValues.otp);
const response = await api.post(url, formdata);
dispatch({
type: "VERIFY_OTP",
payload: response,
});
dispatch(stopSubmitting());
await SecureStore.setItemAsync("userToken", response.data.access_token);
};
};
export const checkUser = () => {
return async (dispatch) => {
const token = await SecureStore.getItemAsync("userToken");
const url = `/me`;
const response = await api
.post(url, { token })
.then((res) => {
return res;
})
.catch((error) => {
return error.response;
});
dispatch({
type: "CHECK_USER",
payload: response,
});
};
};
The Problem
you are mixing two different implementations in checkUser to handle a promise which is clearly incorrect and leads to the issues.
The Solution
since your other parts of codes use the async/await so try to remove then/catch block from the response constant:
const checkUser = () => {
return async (dispatch) => {
const url = '/me';
try {
const token = await SecureStore.getItemAsycn("userToken);
const response = await api.post(url, {token})
dispatch({type: "CHECK_USER", payload: response})
} catch (error) {
// to proper action on failure case
}
}
}
Note 1: always use async/await in try/catch block. more on MDN documentation.
Optional
since you are trying to call two async actions (once for getting token and once for calling '/me' API), I encourage you to use two different try/catch blocks to handle the failure case for each async action separately. for example:
const checkUser = () => {
return async (dispatch) => {
let token = null;
try {
token = await SecureStore.getItemAsync("userToken");
} catch (err) {
// proper action in case of failure on getting the token from storage
}
// you may need to ignore API calls without the token, so:
try {
if(token){
const url = '/me';
const response = await api.post(url, {token});
dispatch({type: "CHECK_USER", payload: response});
}
} catch (err) {
// take proper action with the error response according to your applicaiton
}
}
}
https://obikes.page.link/d6o5/?ref=10959bc
I am using axios this is my invite link in my app i want to get data after query string i need ref code ref=10959bc ,how can i get this query data 10959bc in react native
i am unable to find any solution
React.useEffect(async () => {
const getValue = await AsyncStorage.getItem('token');
await getReferal().then(response => {
console.log(response.data.refferalUrl); //https://obikes.page.link/d6o5/?ref=10959bc
// refer code
})
.catch(error => {
console.log(error);
});
A pure JS approach:
React.useEffect(async () => {
const getValue = await AsyncStorage.getItem('token');
await getReferal().then(response => {
console.log(response.data.refferalUrl);
// refer code:
const url = response.data.refferalUrl
let regex = /[?&]([^=#]+)=([^&#]*)/g, params = {}, match;
while ((match = regex.exec(url))) {
params[match[1]] = match[2];
}
console.log(params) // => {ref: "10959bc"}
})
.catch(error => {
console.log(error);
});
Use the qs npm package to get the query string params from a string.
https://github.com/ljharb/qs
I'm trying to use fetch to get the contents of the HTML page in React Native, and I'm running it on expo, here:
https://snack.expo.io/#abalja/hellofetch
Basically the code is nothing special, uses 'fetch' which does work for loading .json files, but I can't get it to work for .html files. It just silently fails, and I don't even get an error logged. I'm not sure if this is Expo or ReactNative issue.
const url2 = 'http://www.spiegel.de/sport/fussball/nations-league-italien-trifft-in-der-nachspielzeit-polen-steigt-ab-a-1233219.html#ref=rss'
export default class App extends React.Component {
componentDidMount(){
console.log('did mount, fetching: ' + url2)
fetch(url2)
.then((response) => {
console.log(response) // 1
return response.text()
})
.then((responseText) => {
console.log('fetch text', responseText) // 2
// return responseText.movies;
})
.catch((error) => {
console.error(error);
});
}
render() {
return (
<View style={styles.container}>
</View>
);
}
}
At 1 I get the response logged:
{type:"default",status:200,ok:true,headers:{…},url:"http://www.spiegel.de/sport/fussball/nations-league-italien-trifft-in-der-nachspielzeit-polen-steigt-ab-a-1233219.html",_bodyInit:{…},_bodyBlob:{…}}
type:"default"
status:200
ok:true
►headers:{map:{…}}
url:"http://www.spiegel.de/sport/fussball/nations-league-italien-trifft-in-der-nachspielzeit-polen-steigt-ab-a-1233219.html"
►_bodyInit:{_data:{…}}
►_bodyBlob:{_data:{…}}
At 2 I get absolutely nothing logged.
Promise syntax is confusing to me, so I changed into async-await:
async componentDidMount() {
console.log('did mount, fetching: ' + url2);
try {
let response = await fetch(url2);
let text = await response.text();
console.log(text)
} catch(e) {
console.log(e)
}
}
It works! You can check it here: https://snack.expo.io/#aazwar/fetch-url
It's because you are parsing your Response as text and not as json, and then trying to call object-key against string. Basically what you have at that point is string which looks like json. Parse your response with .json()-method instead.
return response.text() should be therefore return response.json()
to reconstruct your code
// With .then()
fetch(url2)
.then((response) => {
return response.json()
})
.then((responseJson) => {
return responseJson.movies;
})
.catch((error) => {
console.error(error);
});
// OR with await/async
const response = await fetch(url2)
const json = await response.json() // As '.json()' is async function as well
return json.movies
I would succest using await/async since syntax is much more cleaner and it start's to be way to go.
in my React Native app I receive a token from an API. Everytime the app sends a request to the server this token is needed. I save the token in the AsyncStorage:
export const onSignIn = (value) => AsyncStorage.setItem('USER_TOKEN', value);
In many different parts of the app I need this token and therefore I wanted to use a function, that extracts the information out of the token:
export const getTokenInfo = async () => {
try{
const value = await AsyncStorage.getItem('USER_TOKEN')
.then((res) => {
const jsonData = jwtDecode(res);
return jsonData;
})
}
catch(e){
console.log('caught error', e);
}
}
When calling the function in other Components it just returns the Promise itself and not the token. Is there a possibility to get the token, but not the promise? A possible approach was to use setState() to store the token in a state, but there are some components like DrawerNavigator that are not in a class.
Thanks!
Your forgot to return the value on your getTokeninfo function
export const getTokenInfo = async () => {
try{
const value = await AsyncStorage.getItem('USER_TOKEN')
.then((res) => {
const jsonData = jwtDecode(res);
return jsonData;
})
return value // <---- you forgot this line
}
catch(e){
console.log('caught error', e);
}
}