React native image picker not displaying selected image - react-native

I don't seem to be able to render the image selected when using react-native-image-picker. After selecting an image from the device library the default image stays selected
My first thoughts are it has something to do with the path
defaultImageUri http://localhost:8081/assets/src/assets/images/emptyavatar.jpg?platform=ios&hash=54674069799117e0326e575845f59679
imageURI file:///Users/lewisr66/Library/Developer/CoreSimulator/Devices/CA90AEB9-E017-4E46-9D5F-A4761F060334/data/Containers/Data/Application/71492FA8-D8D3-4CC5-B810-E64EC1C08C6A/tmp/999D74FB-BCE6-46BC-AAF3-0A81FEFDB3F0.jpg
But I'm unsure it this has anything to do with it. Have I done something wrong here?
import React, {useContext, useState} from 'react';
import {Image} from 'react-native';
import {Avatar} from 'native-base';
import defaultProfileImage from '../../assets/images/emptyavatar.jpg';
import {launchImageLibrary} from 'react-native-image-picker';
export const UserProfile = () => {
// Image Picker
const defaultImageUri = Image.resolveAssetSource(defaultProfileImage).uri;
const [imageURI, setImageURI] = useState(defaultImageUri);
const options = {
title: 'Select Image',
type: 'library',
options: {
maxHeight: 200,
maxWidth: 200,
selectionLimit: 1,
mediaType: 'photo',
includeBase64: false,
},
};
const openGallery = async () => {
const imageData = await launchImageLibrary(options);
setImageURI(imageData.assets[0].uri);
};
return (
<Avatar source={{uri: imageURI}} w="24" h="24" />
);
}

Try something like this:-
const handleOpenLibrary = () => {
let options = {
mediaType: "photo",
//rest your options
};
launchImageLibrary(options, (response) => {
if (response.didCancel) {
} else if (response.error) {
} else if (response.customButton) {
Alert.alert(response.customButton);
} else {
let source = response;
console.log("source", source);
let imageSizeInKb = source.fileSize / 1024
let imageSizeInMb = imageSizeInKb / 1024
if (imageSizeInMb < 10) {
setImageURI(source.uri)
}
else {
Toast.show({
text1: "AppName",
text2: "size error",
type: "error",
position: "top"
});
}
}
});
};
And in return:-
<View style={{flex:1}}>
<Image
source={{uri:imageURI}}
style={{height:50,width:50}}/>
</View>

Related

Uploading image to AWS S3

i am a beginner in react native. my problem is, i am trying to send image from camera to aws s3. this is my latest code.
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity, Button, Image } from 'react-native';
import ImagePicker from 'react-native-image-picker';
import { RNS3 } from 'react-native-aws3';
import fs from 'react-native-fs';
import Buffer from 'buffer';
import AWS from 'aws-sdk';
function uploadToS3(image){
const filename = "the_file.jpeg";
const options = {
keyPrefix: "uploads/",
bucket: "this is bucketname",
region: "this is region",
accessKey: "this is access key",
secretKey: "this is secret key",
successActionStatus: 201
}
try{
const s3 = new AWS.S3({accessKeyId: options.accessKey, secretAccessKey:options.secretKey, region:options.region});
var UploadURL;
const params = {Bucket: options.bucket, Key: options.keyPrefix+filename, ContentType: image.type};
s3.getSignedUrl('putObject', params, function (err, url) {
console.log('Your generated pre-signed URL is', url);
UploadURL = url;
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log("ok: ", xhr.response);
alert("success");
} else {
console.log("no: " , xhr.response);
alert("no");
}
}
}
xhr.open('PUT', UploadURL)
xhr.setRequestHeader('Content-Type', image.type)
xhr.send({image})
});
} catch(error){
console.log("err : ",error)
}
}
class HomeScreen extends React.Component {
constructor(props) {
global.currentScreenIndex = 'HomeScreen';
super(props);
this.state = {
resourcePath: {},
requestStatus: {},
employees: {},
response: {},
};
}
cameraLaunch = (id) => {
console.log(id);
let options = {
title: 'Select Picture',
storageOptions: {
skipBackup: true,
path: 'images',
},
base64: true,
maxWidth: 400,
maxHeight: 400
};
ImagePicker.launchCamera(options, (res) => {
//console.log('Response = ', res);
if (res.didCancel) {
console.log('User cancelled image picker');
} else if (res.error) {
console.log('ImagePicker Error: ', res.error);
} else if (res.customButton) {
console.log('User tapped custom button: ', res.customButton);
alert(res.customButton);
} else {
let source = res;
this.setState({
resourcePath: source,
});
uploadToS3(res);
}
});
}
render(){
return (
<View style={{ flex: 1, alignItems: 'center', marginTop: 100 }}>
<Button
onPress={()=>this.cameraLaunch(1)}
title="OpenCamera"
color="#841584"
/>
<Text style={{ alignItems: 'center' }}>
{this.state.resourcePath.uri}
</Text>
<Image source={this.state.resourcePath} />
</View>
);
}
};
export default HomeScreen;
there is nothing wrong with the camera or presigned url generation. if run, there will be the_file.jpeg in "this is bucket name"/uploads/the_file.jpeg, but the problem is, its size is 0 byte. i have tried to send just image.data, but apparently it just make the_file.jpeg become a "txt file" with "jpeg" extension. please help.
ps : i am aware on how insecure this code.
It looks like you missed the purpose of presigned URLs which is to upload objects without the need of AWS credentials. In your example, you are initializing the S3 client using the AWS credential, in that case, you can simply use s3.upload function to upload your file.
I had the same issue and nothing helped. This is what I did.
Make sure you follow the amplify guide for setting up a app. amplify init, amplify add auth, amplify push, and then amplify add storage and then do this.
import Amplify, { Storage } from 'aws-amplify'
import config from './src/aws-exports'
// import awsconfig from './aws-exports';
// Might need to switch line 7 to awsconfig
Amplify.configure(config)
import { StatusBar } from 'expo-status-bar';
import React, { useState, useEffect } from 'react';
import { Button, Image, View, Platform, StyleSheet, Text, TextInput } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
function App() {
const [image, setImage] = useState(null)
const [name, setName] = useState('Evan Erickson')
useEffect(() => {
(async () => {
if (Platform.OS !== 'web') {
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (status !== 'granted') {
alert('Sorry, we need camera roll permissions to make this work!');
}
}
})();
}, []);
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
console.log(result)
async function pathToImageFile(data) {
try {
const response = await fetch(data);
const blob = await response.blob();
await Storage.put(`customers/${name}`, blob, {
contentType: 'image/jpeg', // contentType is optional
});
} catch (err) {
console.log('Error uploading file:', err);
}
}
// later
pathToImageFile(result.uri);
}
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button title="Pick an image from camera roll" onPress={pickImage} />
{image && <Image source={{ uri: image }} style={{ width: 200, height: 200 }} />}
<Button title="Upload image" onPress={() => {alert(image)}} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default withAuthenticator(App)

How to pass api data from react native to html and vice-versa in react-native-html-to-pdf

i am using react-native-html-to-pdf package to create a pdf file i want to pass the api response from react-native to html and receive the data from html. the options available for this npm package is very minimum
There is no options in the package so that i can use it, can someone help me with this ?
Below is my code.
import React, { Component } from 'react';
import { Text, TouchableOpacity, View, StyleSheet, Image, PermissionsAndroid, Platform,} from 'react-native';
import RNHTMLtoPDF from 'react-native-html-to-pdf';
import htmlContent from './htmlContent'
export default class App extends Component {
constructor(props) {
super(props)
this.state = {
apiData: [],
filePath: ''
}
}
askPermission() {
var that = this;
async function requestExternalWritePermission() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
{
title: 'External Storage Write Permission',
message:
'App needs access to Storage data in your SD Card ',
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
that.createPDF();
} else {
alert('WRITE_EXTERNAL_STORAGE permission denied');
}
} catch (err) {
alert('Write permission err', err);
console.warn(err);
}
}
if (Platform.OS === 'android') {
requestExternalWritePermission();
} else {
this.createPDF();
}
}
componentDidMount(){
fetch(`http://API`)
.then((response) => response.json())
.then((responseJson) => {
**console.log("DATA", responseJson) // NEED TO SEND THIS DATA TO "HTML"**
this.setState(() => ({
apiData: responseJson
}))
})
}
async createPDF() {
let options = {
html:htmlContent, // API DATA SHOULD BE SENT TO HTML
fileName: 'RTT Report',
directory: 'docs',
width: 800,
};
let file = await RNHTMLtoPDF.convert(options);
console.log(file.filePath);
this.setState({filePath:file.filePath});
}
render() {
return (
<View style={styles.MainContainer}>
<TouchableOpacity onPress={this.askPermission.bind(this)}>
<View>
<Image
//We are showing the Image from online
source={{
uri:
'https://raw.githubusercontent.com/AboutReact/sampleresource/master/pdf.png',
}}
//You can also show the image from you project directory like below
//source={require('./Images/facebook.png')}
style={styles.ImageStyle}
/>
<Text style={styles.text}>Create PDF</Text>
</View>
</TouchableOpacity>
<Text style={styles.text}>{this.state.filePath}</Text>
</View>
);
}
}
In createPDF method :
// html:htmlContent, // API DATA SHOULD BE SENT TO HTML
html: this.state.apiData // <-- you have stored your html in the state
EDIT:
Probably I was too fast answering, now I think I got your point , here you have an example :
// html: '<h1>PDF TEST</h1>', <-- example from react-native-html-to-pdf
const exampleData = [
{
title: "Element title",
content: "Element content"
},
{
title: "Other title",
content: "Other element content"
}
]
function generateHTML () {
const data = exampleData
// const data = this.state.apiData // <-- in your case
let htmlContent = '<html><body>'
htmlContent += data.map(entry => {
return `<h5>${entry.title}</h5> <br /> <p>${entry.content}</p>`
}).join(' ')
htmlContent += '</body></html>'
return htmlContent
}

Invariant Violation in React Native: Text strings must be rendered within a <Text> component

I'm working on a React-Native project with REST APis, and I've currently got an invariant violation error. I've experienced this before, but I can't quite figure out what is causing it and how to fix it. If someone could point me in the right direction, I would really appreciate it! The full error is pictured below, and appears to be referencing a number of tags in the code, so I'm unsure exactly where it is originating. Thank you for reading, and thanks in advance!
The code is here:
import React, { Component } from 'react'
import { View, Text, Image, StyleSheet, FlatList} from 'react-native';
import * as Font from 'expo-font';
import styled from 'styled-components';
import dimensions from '../components/ScreenSize';
import colours from '../components/Colours';
import { Audio } from 'expo-av';
import { TouchableHighlight } from 'react-native-gesture-handler';
const client_id = {Client_ID}
const client_secret = {Client_Secret}
const item = ({item}) => (
<View style={{ flex:1, flexDirection: 'column', margin:1}}>
<TouchableHighlight onPress={() => this.fetchTracks(item.id)}>
<View>
<Text>{item.name}</Text>/>
</View>
</TouchableHighlight>
</View>
)
export default class HomeScreen extends React.Component {
state={
fontsLoaded:false,
}
async componentDidMount() {
await Font.loadAsync({
'montserrat-regular': require('../assets/fonts/Montserrat/Montserrat-Regular.ttf'),
'montserrat-light': require('../assets/fonts/Montserrat/Montserrat-Light.ttf'),
'montserrat-semibold': require('../assets/fonts/Montserrat/Montserrat-SemiBold.ttf'),
'montserrat-bold': require('../assets/fonts/Montserrat/Montserrat-Bold.ttf'),
}
).then(() => this.setState({ fontsLoaded:true }))
this.getToken();
this.setAudio();
}
constructor (props) {
super(props)
this.playbackInstance=null;
this.state = {
playing:false,
token: '',
DATA:[],
};
}
setAudio=() => {
Audio.setAudioModeAsync({
allowsRecordingIOS:false,
interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DO_NOT_MIX,
playsInSilentModeIOS: true,
shouldDuckAndroid: true,
interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DO_NOT_MIX,
playThroughEarpieceAndroid: false,
});
}
componentDidCatch(error, info)
{
console.log(error, info.componentStack);
}
getToken = async() =>
{
try
{
const getspotifytoken = await fetch("https://accounts.spotify.com/api/token",
{
method:'POST',
body: `grant_type=client_credentials&client_id=${client_id}&client_secret=${client_secret}`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
const spotifytoken = await getspotifytoken.json();
this.setState({
token: spotifytoken.access_token
});
console.log(this.state.token);
}
catch(err)
{
console.log("Error fetching data", err);
}
}
search = async () => {
try
{
console.log("Searching: mood")
const spotifyApiCall = await fetch(`https://api.spotify.com/v1/browse/categories/mood/playlists?`, {
headers: {
Accept: 'application/json',
Authorization: `Bearer ${this.state.token}`,
"Content-Type":'application/json'
}
})
const spotify = await spotifyApiCall.json();
console.log("Items", spotify);
this.setState({
DATA: spotify.playlists.items,
})
}
catch (err)
{
console.log("Error fetching data", err);
}
}
fetchTracks = async (playlistId) => {
console.log('Playlist ', playlistId)
try
{
const getplaylist = await fetch(`https://api.spotify.com/v1.playlist/${playlistId}`,
{
method:'GET',
headers: {
Accept:"application/json",
Authorization:`Bearer ${this.state.token}`,
"Content-Type":"application/json"
}
});
const playlist = await getplaylist.json();
console.log('music ', playlist.tracks.items[0].preview_url);
}
catch (err)
{
console.log("Error fetching data ", err);
}
}
async _loadNewPlaybackInstance(playing, track) {
if(this.playbackInstance != null)
{
await this.playbackInstance.unloadAsync();
this.playbackInstance.setOnPlaybackStatusUpdate(null);
this.playbackInstance = null;
}
const source = {uri: track};
const initialStatus = {
shouldPlay: true,
rate: 1.0,
shouldCorrectPitch: true,
volume: 1.0,
isMuted: false
};
const {sound, status} = await Audio.Sound.createAsync(
source.initialStatus);
this.playbackInstance=sound;
this.playbackInstance.setIsLoopingAsync(false);
this.playbackInstance.playAsync();
if (this.state.selected === playlistId) {
console.log("Playing, so stop");
this.setState({selected:null});
this.playbackInstance.pauseAsync();
return;
}
this.setState({ selected:playlistId});
this._loadNewPlaybackInstance(true, playlist.tracks.items[0].preview_url);
}
render() {
if(!this.state.fontsLoaded ) {
return null
}
return (
<Container>
<Titlebar>
<Title>Music</Title>
</Titlebar>
<HeaderBar2>
<TouchableHighlight onPress={() => this.search()}>
<Header2>Playlists for your Mood</Header2>
</TouchableHighlight>
</HeaderBar2>
<View style={styles.MainContainer}>
{
this.state.DATA.length == 0 &&
<Text style={{padding:10, color:'#D3D3D3'}}/>
}
<FlatList
data = {this.state.DATA}
renderItem={item}
keyExtractor = {item.id}
numColumns={2}
extraData = {this.state}
/>
</View>
</Container>
);
}
}
I think u just have a little typo ..
check this line: <Text>{item.name}</Text>/>
change the last Text to </Text>

How to open a pdf from my flatlist in react-native?

Im trying to pick a file (pdf-file) from a module called react-native-file-picker. This works ok, and gaves me name, type, path and uri.
After this, i display the name of the document that i picked in a flatlist.
Now, what i want is to "onPress" of the item in the flatlist, open the document with some pdf viewer or something like that.
I've already tried to use other modules like react-native-view-pdf and react-native-pdf and react-native-pdf-view but i cant access the state of my uri with either of them.
The last one that i used it was react-native-file-viewer and doesn't work very well because it doesn't open the item on press.
This is my actual code.
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity, Button, TextInput,
Dimensions, FlatList } from 'react-native';
import AsyncStorage from '#react-native-community/async-storage'
import FilePickerManager from 'react-native-file-picker';
import FileViewer from 'react-native-file-viewer';
global.myfunction = function myfunction() {
FilePickerManager.showFilePicker(null, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled file picker');
}
else if (response.error) {
console.log('FilePickerManager Error: ', response.error);
}
else {
this.storeItem(response)
}
});
};
export default class Docs extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
title: 'Docs',
header: null
}
};
state = {
arr: [],
local: '',
password: '',
obj: null,
count: 1,
image: {},
b64: '',
isModalVisible: false,
pdfuri: null,
};
pdf = () => {
FilePickerManager.showFilePicker(null, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled file picker');
}
else if (response.error) {
console.log('FilePickerManager Error: ', response.error);
}
else {
this.storeItem(response)
this.setState({
pdfuri: response.path
});
}
});
}
toggleModal = (item) => {
this.setState({ isModalVisible: !this.state.isModalVisible, obj: item });
};
storeItem(item) {
try {
//we want to wait for the Promise returned by AsyncStorage.setItem()
//to be resolved to the actual value before returning the value~
console.log(item)
var joined = this.state.arr.concat(item);
console.log('files ', joined)
this.setState({ arr: joined })
AsyncStorage.setItem('files', JSON.stringify(joined));
console.log(this.state.arr)
} catch (error) {
console.log(error.message);
}
}
componentDidMount() {
//Here is the Trick
const { navigation } = this.props;
}
componentWillMount() {
AsyncStorage.getItem('files').then(array => {
item = JSON.parse(array)
item ? this.setState({ arr: item }) : null;
console.log(this.state.arr)
})
}
verpdf() {
const path =
"content://com.android.providers.downloads.documents/document/4183"
FileViewer.open(path, { showOpenWithDialog: true })
.then(() => {
// success
})
.catch(error => {
// error
});
}
render() {
return (
<View style={[styles.container, { marginTop: 20 }]}>
<FlatList
data={this.state.arr}
renderItem={({ item }) => <TouchableOpacity onPress=
{this.verpdf(item)} style={{ marginBottom: 10, marginTop: 10, alignItems: 'center' }}>
<Text>{item.fileName}</Text></TouchableOpacity>}
/>
<Button title='ok' onPress={this.pdf}></Button>
</View>
);
}
}
How should i do this?
Try to change the event handler from
onPress=
{this.verpdf(item)}
to
onPress=
{()=>this.verpdf(item)}
Like #Oleg said, to open a certain item i needed to change the event handler to a arrow function.
onPress = {this.verpdf(item)}
to
onPress= {()=>this.verpdf(item)}
After that i wanted to open a certain item from my flatlist which i did:
verpdf(item) {
const path = item.path
FileViewer.open(path, { showOpenWithDialog: true })
.then(() => {
// success
})
.catch(error => {
// error
});
}

React native signed APK crash

Signed APK crash after launch, in logCat i got requiring unknown module 'React'
Debug application works fine, but in logCat i got >> Requiring module 'React' by name is only supported for debugging purposes and will BREAK IN PRODUCTION!
React v15.4.1, React native v0.39.2 ?
Sorry for my english
this is my index.android.js
import React from 'react';
import {AppRegistry} from 'react-native';
import myapp from './index_start.js';
AppRegistry.registerComponent('myapp', () => myapp);
and index_start.js
import React, { Component } from "react";
import {
StyleSheet,
AppRegistry,
Text,
Image,
View,
AsyncStorage,
NetInfo,
StatusBar,
Navigator,
Dimensions
} from 'react-native';
// Window dismensions
const { width, height } = Dimensions.get('window');
// Device infos
import DeviceInfo from 'react-native-device-info';
// Native SplashScreen
import SplashScreen from 'react-native-splash-screen';
// Spinner
import Spinner from 'react-native-spinkit';
// Models
import User from './model/UserModel';
// Json data for initial launch
var DB = require('./DB.json');
// Components
import Stage from './components/stage/stage.js'
import Player from './components/player/player.js'
import Settings from './components/settings/settings.js'
import House from './stages/house/house.js'
// LocalStorage key
var USER_KEY = 'user_key';
const routes = [
{name: 'loading'},
{name: 'stage', component: Stage},
{name: 'house', component: House},
{name: 'settings', component: Settings}
];
const _navigator = null;
export default class myapp extends Component {
constructor(props) {
super(props);
this.state = {
isConnected: false,
isLoading: true,
_navigator: null,
stages: null
}
}
componentWillMount() {
// check if connected
this._checkConnexionType();
}
componentDidMount() {
SplashScreen.hide();
this._loadInitialData();
}
componentDidUpdate() {
// console.log(this.state.stages)
if (!this.state.isLoading && this.state.stages !== null) {
_navigator.push({
name: 'stage',
passProps: {
data: this.state.stages
}
})
}
}
/**
* Load localStorage Data
*/
async _loadInitialData() {
// GET User LocalStorage
if (this.state.stages == null) {
var localData;
//AsyncStorage.removeItem(USER_KEY)
AsyncStorage.getItem(USER_KEY).then((data) => {
if (data !== null) {
var localData = JSON.parse(data);
// User.uuid = localData.uuid;
User.setStages(localData.stages)
this.setState({
'stages' : localData.stages
})
} else {
var storage = {};
storage.setUiid = DeviceInfo.getUniqueID();
storage.stages = DB.stages;
AsyncStorage.setItem(USER_KEY, JSON.stringify(storage));
this.setState({
'stages' : DB.stages
})
}
})
}
if (this.state.isConnected) {
// var rStages = this._loadRemoteStages();
// console.log(rStages);
}
// Change state
setTimeout((function() {
this.setState({
'isLoading': false
})
}).bind(this), 1500);
}
/**
* GET stages from remote DB
*/
async _loadRemoteStages() {
await fetch(API_URL)
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson)
return responseJson;
})
.catch((error) => {
console.error(error);
});
}
/**
* CHECK IF user is connected to Network
* SET bool to state isLoading
*/
_checkConnexionType() {
NetInfo.isConnected.fetch().then(response => {
this.setState({ isConnected: response})
})
}
_renderScene(route, navigator) {
_navigator = navigator;
if (route.name == 'loading') {
return (
<View style={styles.container}>
<StatusBar hidden={true} />
<Image
style={{width: width, height: height}}
source={require('./img/screen.jpg')}
/>
<View style={styles.loading}>
<Text style={styles.loadingText}>CHARGEMENT</Text>
<Spinner type="ThreeBounce" color={'#fff'}/>
</View>
</View>
)
} else if (route.name == 'stage') {
return (
<Stage navigator={_navigator} {...route.passProps}/>
)
} else if (route.name == 'player') {
return (
<House navigator={_navigator} {...route.passProps}}/>
)
} else if (route.name == 'settings') {
return (
<Settings navigator={_navigator} {...route.passProps}/>
)
}
}
render() {
return (
<Navigator
initialRoute={{name: 'loading'}}
configureScene={() => Navigator.SceneConfigs.FloatFromBottomAndroid}
renderScene={this._renderScene.bind(this)}
/>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
loading: {
flex: 1,
position: 'absolute',
bottom: 50,
left: 0,
right: 0,
alignItems: 'center',
},
loadingText:{
flex: 1,
fontFamily: 'CarterOne',
fontSize: 20,
color: '#fff'
}
});