Download file using download link from api - android

I have a develop website where i can upload a single file and multiple file which give me the download link. I also make and api to fetch my id. (http://lkcfesnotification.000webhostapp.com/api/notifications). From the api i can fetch the image using JSON.parse but when come to my attachment(file) i want to be a hyperlink to download from the browser. from the api i am certain with the path with store in my storage. and the storage also have my images which i can view my images How can i do this?
I use let attachment = member && JSON.parse(member.attachment); then
Linking.openURL('http://lkcfesnotification.000webhostapp.com/storage/' + attachment[0]) } >Click here for to Download file but this show me page not found
import React, { Component } from 'react';
import {
Alert,
Image,
StyleSheet,
ScrollView,
View,
Text,
Linking,
} from 'react-native';
import {
InputWithLabel
} from './UI';
import { FloatingAction } from 'react-native-floating-action';
type Props = {};
export default class ShowScreen extends Component<Props> {
static navigationOptions = ({navigation}) => {
return {
title: navigation.getParam('headerTitle')
};
};
constructor(props) {
super(props)
this.state = {
id: this.props.navigation.getParam('id'),
member: '',
};
this._load = this._load.bind(this);
}
componentDidMount() {
this._load();
}
_load() {
let url = 'http://lkcfesnotification.000webhostapp.com/api/notifications/' + this.state.id;
fetch(url)
.then((response) => {
if(!response.ok) {
Alert.alert('Error', response.status.toString());
throw Error('Error ' + response.status);
}
return response.json()
})
.then((member) => {
this.setState({member});
})
.catch((error) => {
console.error(error);
});
}
render() {
let member = this.state.member;
// let af = 'http://lkcfesnotification.000webhostapp.com/storage/';
console.log(member);
console.log(member.image);
let image = member && JSON.parse(member.image);
let attachment = member && JSON.parse(member.attachment);
return (
<View style={styles.container}>
<ScrollView>
<InputWithLabel style={styles.output}
label={'Title'}
value={member ? member.title : ''}
orientation={'vertical'}
multiline={true}
editable={false}
/>
<InputWithLabel style={styles.output}
label={'Department'}
value={member ? member.department : ''}
orientation={'vertical'}
editable={false}
/>
<InputWithLabel style={styles.output}
label={'Publish'}
value={member ? member.updated_at : ''}
orientation={'vertical'}
editable={false}
/>
<InputWithLabel style={[styles.output, {height: 600, textAlignVertical: 'top'}]}
label={'Description'}
value={member ? member.description : ''}
orientation={'vertical'}
editable={false}
multiline={true}
/>
<Text>
{image && image.length && image.map(image => {
return <Image
source={{uri: 'http://lkcfesnotification.000webhostapp.com/storage/' + image}}
style={{width: 300, height: 300}}
orientation={'vertical'}
/>
})
}
</Text>
<Text style={styles.TextStyle} onPress={ ()=> Linking.openURL('http://lkcfesnotification.000webhostapp.com/storage/' + attachment[0]) } >Click here for to Download file</Text>
<Text style={styles.TextStyle} onPress={ ()=> Linking.openURL(member.link) } >Click here for More Detail</Text>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
backgroundColor: '#fff',
},
output: {
fontSize: 24,
color: '#000099',
marginTop: 10,
marginBottom: 10,
},
TextStyle: {
color: '#E91E63',
textDecorationLine: 'underline',
fontSize: 30
},
});
I want to press the hyperlink i directly connect to default browser of the device and download the file

Related

After implementing this auto suggestion text input in my react native app the value stored is only what was typed in not the suggestion after clicking

So I have tried to implement this code from user illusionist from another issue concerning auto filling text input with suggested text here in react native LINK: How to get suggestions while typing in text-input in react-native
this is how I implemented it >
import { Menu, TextInput } from "react-native-paper";
import React, { useState } from "react";
const Autocomplete = ({
value: origValue,
label,
data,
containerStyle,
onChange: origOnChange,
icon = 'bike',
style = {},
menuStyle = {},
right = () => {},
left = () => {},
}) => {
const [value, setValue] = useState(origValue);
const [menuVisible, setMenuVisible] = useState(false);
const [filteredData, setFilteredData] = useState([]);
const filterData = (text) => {
return data.filter(
(val) => val?.toLowerCase()?.indexOf(text?.toLowerCase()) > -1
);
};
return (
<View style={[containerStyle]}>
<TextInput
onFocus={() => {
if (value.length === 0) {
setMenuVisible(true);
}
}}
// onBlur={() => setMenuVisible(false)}
label={label}
right={right}
left={left}
style={style}
onChangeText={(text) => {
origOnChange(text);
if (text && text.length > 0) {
setFilteredData(filterData(text));
} else if (text && text.length === 0) {
setFilteredData(data);
}
setMenuVisible(true);
setValue(text);
}}
value={value}
/>
{menuVisible && filteredData && (
<View
style={{
flex: 1,
backgroundColor: 'white',
borderWidth: 2,
flexDirection: 'column',
borderColor: 'grey',
}}
>
{filteredData.map((datum, i) => (
<Menu.Item
key={i}
style={[{ width: '100%' }, menuStyle]}
icon={icon}
onPress={() => {
console.log(datum)
setValue(datum);
console.log(value)
setMenuVisible(false);
}}
title={datum}
/>
))}
</View>
)}
</View>
);
};
export default Autocomplete;
and in another page I import autocomplete and like here:
const [typZavady, setTypZavady] = useState('');
<Autocomplete
value={''}
style={[novaStyle.input]}
containerStyle={novaStyle.autocompleteContainer}
label="Typ závady"
data={['Svetla', 'Stoličky', 'Tabula', 'Projektor', 'Topenie', 'Počítače', 'Dvere', 'Iné']}
menuStyle={{backgroundColor: 'white'}}
onChange={newTyp => setTypZavady(newTyp)}
/>
However when I type and click on one of the suggested words only the part of the word I type in is stored in the const typZavady not the selected suggested word. I fiddled a bit with the code with no luck.

Cannot Render Image from API

I have created my own website and api which is (https://lkcfesnotification.000webhostapp.com) i already upload the image and can view as (http://lkcfesnotification.000webhostapp.com/storage/notifications/August2019/c1nsEktOjtSloxEtnL4d.jpg). And my api for this id is (http://lkcfesnotification.000webhostapp.com/api/notifications/33). But when i try to fetch the api i can display all my text but not my image and hyperlink to download file. How to solve this issue
I try to use this but still no luck
{{ uri: member.image }}
<Image
value={member ? member.image : ''}
source={{uri: 'http://lkcfesnotification.000webhostapp.com/storage/' + member}}
style={{width: 60, height: 60}}
/>
I expected to get my my image and my file using hyperink to download through google browser
import React, { Component } from 'react';
import {
Alert,
Image,
StyleSheet,
ScrollView,
View,
Text,
} from 'react-native';
import {
InputWithLabel
} from './UI';
import { FloatingAction } from 'react-native-floating-action';
type Props = {};
export default class ShowScreen extends Component<Props> {
static navigationOptions = ({navigation}) => {
return {
title: navigation.getParam('headerTitle')
};
};
constructor(props) {
super(props)
this.state = {
id: this.props.navigation.getParam('id'),
member: [],
};
this._load = this._load.bind(this);
}
componentDidMount() {
this._load();
}
_load() {
let url = 'http://lkcfesnotification.000webhostapp.com/api/notifications/' + this.state.id;
fetch(url)
.then((response) => {
if(!response.ok) {
Alert.alert('Error', response.status.toString());
throw Error('Error ' + response.status);
}
return response.json()
})
.then((member) => {
this.setState({member});
})
.catch((error) => {
console.error(error);
});
}
render() {
let member = this.state.member;
// let af = 'http://lkcfesnotification.000webhostapp.com/storage/';
console.log(member);
console.log(member.image);
//let image = JSON.parse(member.image)
return (
<View style={styles.container}>
<ScrollView>
<InputWithLabel style={styles.output}
label={'Title'}
value={member ? member.title : ''}
orientation={'vertical'}
editable={false}
/>
<InputWithLabel style={styles.output}
label={'Department'}
value={member ? member.department : ''}
orientation={'vertical'}
editable={false}
/>
<InputWithLabel style={styles.output}
label={'Publish'}
value={member ? member.updated_at : ''}
orientation={'vertical'}
editable={false}
/>
<InputWithLabel style={[styles.output, {height: 800, textAlignVertical: 'top'}]}
label={'Description'}
value={member ? member.description : ''}
orientation={'vertical'}
editable={false}
multiline={true}
/>
<Image
value={member ? member.image : ''}
source={{uri: 'http://lkcfesnotification.000webhostapp.com/storage/' + this.state.member.image[0]}}
style={{width: 60, height: 60}}
/>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
backgroundColor: '#fff',
},
output: {
fontSize: 24,
color: '#000099',
marginTop: 10,
marginBottom: 10,
},
});
You are getting array of image in member object. Which is also stringified version, you need to parse it to use further.
You can try this.
render() {
let member = this.state.member;
let af = 'http://lkcfesnotification.000webhostapp.com/storage/';
let image = member && JSON.parse(member.image) //parse your array first
return (
<View style={styles.container}>
<ScrollView>
...
<Image
source={{uri: 'http://lkcfesnotification.000webhostapp.com/storage/' + image[0]}}
style={{width: 60, height: 60}}
/>
</ScrollView>
</View>
Update
Demo
Tested with below JSON directly, because we are getting CORS error while accessing your URL.
{"id":33,"title":"UTAR (Sungai Long Campus) Career Day","description":"<p style=\"margin: 0px 0px 6px; font-family: Helvetica, Arial, sans-serif; color: #1c1e21;\">DARP s organizing UTAR (Sungai Long Campus) Career Day and the details are as follows:-<\/p>\r\n<p> <\/p>\r\n<p style=\"margin: 6px 0px 0px; display: inline; font-family: Helvetica, Arial, sans-serif; color: #1c1e21;\">Date: 1 August 2019 (Thursday)<br \/>Time: 10.00am - 4.00pm<br \/>Venue: Multipurpose Hall (KB Block), Sungai Long Campus<\/p>","image":"[\"notifications\\\/August2019\\\/c1nsEktOjtSloxEtnL4d.jpg\",\"notifications\\\/August2019\\\/WKka4FvUxFyNQpGQHSo8.jpg\",\"notifications\\\/August2019\\\/KWKZ4XnlkjlK7vHEdHln.jpg\",\"notifications\\\/August2019\\\/eNDFFu4hFHFMBEsR94DV.jpg\",\"notifications\\\/August2019\\\/IWH0eg3IpG59qapIoHj3.jpg\"]","attachment":"[{\"download_link\":\"notifications\\\/August2019\\\/SXMtnNb31ndgDnCWNC57.txt\",\"original_name\":\"dsadasdsa.txt\"},{\"download_link\":\"notifications\\\/August2019\\\/CDEZG6tJhrbVuxlfMiBb.txt\",\"original_name\":\"fyprefereance.txt\"}]","department":"D3E","link":null,"created_at":"2019-08-03 03:52:11","updated_at":"2019-08-03 03:52:11","deleted_at":null}
You can check the console.log, how the member.parse gives correct array of image.
Update 2
You can loop over image to get all the images.
{image && image.length && image.map(image => {
return <Image
source={{uri: 'http://lkcfesnotification.000webhostapp.com/storage/' + image}}
style={{width: 60, height: 60}}
/>
})
}
The below would give you some idea on the issue. ( I haven't added complete working code but a code which gives you some idea on the issue)
After seeing your api response, I see that image is an array rather than just an object.
Moreover it's a string which you need to convert to a JSON object.
JSON.parse method can help you with converting your string to JSON object.
From your API, image is an array. Notice the [] which means your image is an array.
This means you either want to display an array of images or just a single image.
If you want all the images to be displayed, iterate through member.image and display it.
If you want to display only single image give below a try
Declare a variable in your render method and use it for your image. (Make sure your member object is not defined before using it
let memberImages = JSON.parse(member.image);
{ memberImages && memberImages[0] &&
<Image
value={member ? member.image : ''}
source={{uri: 'http://lkcfesnotification.000webhostapp.com/storage/' + member.image[0]}}
style={{width: 60, height: 60}}
/>
}

How to fix React Native Webview not showing element

I am developing an app in android using react-native. The problem is when I use WebView, it only works on some devices, mostly the ones with older OS on android.
I have tried using this code and modified it a bit. It worked on some phones, but the elements inside the webview doesn't show in my own phones.
It renders like this, while it should have rendered something like this
Here is the snippet of ListSoal.js that contains the code to the WebView
import React, { Component } from 'react'
import {
ScrollView,
TouchableOpacity,
Alert,
Image,
Modal,
Text,
BackHandler,
WebView,
AsyncStorage,
Dimensions,
Platform
} from 'react-native'
const injectedScript = function () {
function waitForBridge () {
if (window.postMessage.length !== 1) {
setTimeout(waitForBridge, 200)
} else {
let height = 0
if (document.documentElement.clientHeight > document.body.clientHeight) {
height = document.documentElement.clientHeight
} else {
height = document.body.clientHeight
}
}
window.postMessage(height)
}
waitForBridge()
}
export default class ListSoal
extends Component {
state = {
webViewHeight: Number,
webViewHeightAnswer: Number
}
static defaultProps = {
autoHeight: true,
autoHeightAnswer: true
}
constructor (props) {
super(props)
this.state = {
webViewHeight: this.props.defaultHeight,
webViewHeightAnswer: this.props.defaultHeight
}
this._onMessage = this._onMessage.bind(this)
this._onMessageAnswer = this._onMessageAnswer.bind(this)
}
_onMessage (e) {
this.setState({
webViewHeight: parseInt(e.nativeEvent.data)
})
}
_onMessageAnswer (e) {
this.setState({
webViewHeightAnswer: parseInt(e.nativeEvent.data)
})
}
render () {
const { loading } = this.state
if (loading === true) {
return <CommonIndicator color={'#eb6a16'} size={'large'} />
}
if (this.state.soals.length <= 0) {
return (
<View style={styles.notContent}>
<Text style={styles.textNull}>{strings.exercises.notExercises}</Text>
</View>
)
}
const _w = this.props.width || Dimensions.get('window').width - '5%'
const _wA = this.props.width || 265
const _h = this.props.autoHeight ? this.state.webViewHeight : this.props.defaultHeight
const _hA = this.props.autoHeightAnswer ? this.state.webViewHeightAnswer : this.props.defaultHeight
const { animate, soals, no, totalQuestion, displayNumber, selected } = this.state
return (
<View style={styles.mainContainer}>
<View style={styles.topButtonGroup}>
<View style={{flexDirection: 'row', width: '100%', justifyContent: 'space-between'}}>
<View style={{width: '50%'}}>
<TouchableOpacity
onPress={() => this.onNumberModal()}
style={styles.btnNumber}>
<Text style={styles.textbutton}>{strings.exercises.number}</Text>
</TouchableOpacity>
</View>
<View style={{width: '50%'}}>
{
loading === true
? null
: soals[no].question.solution_id === null
? <View
style={[styles.btnSale, {backgroundColor: '#dddddd'}]}>
<Text style={styles.textbutton}>{strings.exercises.solution}</Text>
</View>
: <TouchableOpacity
onPress={() => this.checkSolution()}
style={styles.btnSale}>
<Text style={styles.textbutton}>{strings.exercises.solution}</Text>
</TouchableOpacity>
}
</View>
</View>
<View style={{flex: 1}} />
</View>
<View style={styles.backgquestion}>
<ScrollView>
<View animation={animate} duration={1100} style={styles.listquestion}>
<View style={styles.modal}>
<Text style={styles.number}>Number: {displayNumber + 1}</Text>
</View>
{
soals[no].question.image === null ? null : <Image resizeMode={'stretch'} source={{uri: config.storageUrl + soals[no].question.image}} style={styles.imagequestion} />
}
<View style={styles.soals}>
<WebView
scalesPageToFit={Platform.OS !== 'ios'}
ref={(ref) => { this.webview = ref }}
injectedJavaScript={'(' + String(injectedScript) + ')();'}
scrollEnabled={this.props.scrollEnabled || false}
onMessage={this._onMessage}
javaScriptEnabled={true}
automaticallyAdjustContentInsets={true}
{...this.props}
source={{html: soals[no].question.question}}
style={[{width: _w}, this.props.style, {height: _h}]}
/>
</View>
I have tried changing flex properties many times, but it seems that the problem comes from height = document.body.clientHeight or height document.elementBody.clientHeight because when I changed it to an integer, it worked.
Any suggestions? Thanks in advance

'react-native-image-picker' Error while updating property 'src' of a view managed by: RCTImageView

Does anyone know how to resolve this error?
"Error while updating property 'src' of a view managed by:
RCTImageView"
This error appear when the component is rendering. I think that the images do not give them time to download or something like this.
Dependences:
"firebase": "^4.8.2",
"react": "16.0.0-alpha.12",
"react-native": "0.47",
"react-native-image-picker": "^0.26.7",
ERROR
Gallery.js
import React, { Component } from 'react';
import { View, Image, ScrollView, StyleSheet, Dimensions } from 'react-native';
import { connect } from 'react-redux';
import firebase from '../../config/firebase';
import { nameChanged } from '../../actions';
import { CardSectionTransp, InputBlack } from '../common';
import { SnapshotToArray } from '../../config/helpers';
const { width, height } = Dimensions.get('window');
class EventDetail extends Component {
constructor(props) {
super(props);
this.state = {
images: [],
objImages: []
};
}
componentWillMount() {
firebase.database().ref().child('images').orderByChild('order').once('value', snapshot => {
const images = SnapshotToArray(snapshot);
this.setState({ objImages: images });
const arrayImages = [];
for (const image of images) {
const starsRef = firebase.storage().refFromURL('gs://bealegendapp.appspot.com/images/' + image.path);
// Get the download URL
starsRef.getDownloadURL().then((url) => {
arrayImages.push(url);
this.setState({ objImages: arrayImages });
}).catch((error) => {
// A full list of error codes is available at
// https://firebase.google.com/docs/storage/web/handle-errors
switch (error.code) {
case 'storage/object_not_found':
// File doesn't exist
break;
case 'storage/unauthorized':
// User doesn't have permission to access the object
break;
case 'storage/canceled':
// User canceled the upload
break;
case 'storage/unknown':
// Unknown error occurred, inspect the server response
break;
default:
break;
}
});
}
});
}
onNameChange(text) {
this.props.nameChanged(text);
}
render() {
return (
<ScrollView style={styles.container}>
<CardSectionTransp>
<InputBlack
label="Nombre"
onChangeText={this.onNameChange.bind(this)}
value={this.props.name}
/>
</CardSectionTransp>
<View style={{ flex: 1, flexDirection: 'row', flexWrap: 'wrap', marginTop: 10 }}>
{this.state.objImages && this.state.objImages.length > 0 &&
this.state.objImages.map((image, key) => {
return (
<View key={key} style={{ width: width / 3 }}>
<Image <-------------EEEEEEERRRRRRRROOOOOOORRRRRRR!!!!
source={{ uri: image }}
style={styles.image}
/>
</View>
);
})
}
{this.props.photos &&
this.props.photos.map((image, key) => {
return (
<View key={key} style={{ width: width / 3 }}>
<Image
source={{ uri: image }}
style={styles.image}
/>
</View>
);
})
}
</View>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
paddingBottom: 123
},
image: {
height: height / 5,
resizeMode: 'contain',
width: width / 3,
borderWidth: 1,
borderColor: 'white'
}
});
const mapStateToProps = ({ gallery }) => {
const { name, photos } = gallery;
return { name, photos };
};
export default connect(mapStateToProps, {
nameChanged
})(EventDetail);
Resolved.
I was trying to get storage uri in Component. Is better get it when upload an image and save it in DataBase.
Then... I only to request Images and put storage uri saved in DataBase in source={{ uri: }}.
For anyone else that happens across this issue - i also had it and temporarily got around it with:
{ this.state.myImage !== '' ?
<View>
<Image source={this.state.myImage} />
<Button title="keep img?" onPress={this.setImage} />
</View> : null
}

React-native-image-picker doesn't launch gallery when i select the option

When i click on the select a photo button, Take a photo and select from gallery options pop up. But when i click at those options nothing happens. I am working on windows right now. I tried the same code in mac, selecting the option simply took me to the home screen. Please help.
import React, { Component } from 'react';
import {AppRegistry,View,Text,Image, StyleSheet,PixelRatio,TouchableOpacity } from 'react-native';
import {
Container,
List,
ListItem,
Content,
Footer,
FooterTab,
Header,
Button,
Icon,
Tabs,
Title,
InputGroup,
Input
} from 'native-base';
import{
Actions,
Scene,
Router
}from 'react-native-router-flux';
import ImagePicker from 'react-native-image-picker';
import Reg from './Reg'
export default class Log extends Component{
state = {
avatarSource: null,
};
selectPhotoTapped() {
const options = {
quality: 1.0,
maxWidth: 500,
maxHeight: 500,
storageOptions: {
skipBackup: true
}
};
ImagePicker.showImagePicker(options, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled photo picker');
}
else if (response.error) {
console.log('ImagePicker Error: ', response.error);
}
else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
}
else {
let source = { uri: response.uri };
this.setState({
avatarSource: source
});
}
});
}
render(){
return(
<Container>
<View style={styles.container}>
<TouchableOpacity onPress={this.selectPhotoTapped.bind(this)}>
<View style={[styles.avatar, styles.avatarContainer, {marginBottom: 20}]}>
{ this.state.avatarSource === null ? <Text>Select a Photo</Text> :
<Image style={styles.avatar} source={this.state.avatarSource} />
}
</View>
</TouchableOpacity>
</View>
<Content style={{flex:1, marginTop:80}}>
<List>
<ListItem>
<InputGroup>
<Icon name='ios-at-outline' style={{color:'#5bc0de'}}/>
<Input placeholder="Email" />
</InputGroup>
</ListItem>
<ListItem>
<InputGroup>
<Icon name='ios-lock-outline' style={{color:'#5bc0de'}}/>
<Input placeholder="Password" secureTextEntry />
</InputGroup>
</ListItem>
<View style={{marginTop:10}}>
<Button info style={{alignSelf:'center'}} onPress={Actions.userprofile}>
LOGIN
</Button>
</View>
</List>
</Content>
</Container>
);
}
}
const styles = StyleSheet.create({
container: {
marginTop:50,
justifyContent: 'center',
alignItems: 'center',
},
avatarContainer: {
height:100,
width:100,
borderColor: '#9B9B9B',
borderWidth: 1 / PixelRatio.get(),
justifyContent: 'center',
alignItems: 'center'
},
avatar: {
borderRadius: 75,
width: 150,
height: 150
}
});
Add two permission in AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Categories

Resources