Cannot Render Image from API - android

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}}
/>
}

Related

I have added a picture on bottom. Now my keyboard is not opening

I have added a picture on the bottom of the mobile screen with style as:
bottomView: {
position: 'absolute',
bottom: 0,
},
Above this picture, I have my sign-in form, but because the picture is at the absolute position, it is not letting the keyboard open. I don't want to make this picture relative as it will disturb the picture. Can anyone help me in such a way that I want to keep the picture on the bottom too but want to open the keyboard as well.
Complete code is:
import React from "react";
import { Image, StyleSheet, Text, View ,TextInput,KeyboardAvoidingView} from "react-native";
import Authentication_Button from "./Authentication_Button";
import { SocialIcon } from 'react-native-elements'
const Login = () => {
const [email, setEmail] = React.useState('');
const [password, setPassword] = React.useState('');
return(
<KeyboardAvoidingView behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.container} enabled>
{/* <View style={styles.container}> */}
<Image source={require('./assets/Logo.png')} style={styles.logo}/>
<TextInput
label="Email"
value={email}
onChangeText={email => setEmail(email)}
style={styles.TXT_INPUT}
placeholder="Email"
/>
<TextInput
label="Password"
value={password}
onChangeText={password => setPassword(password)}
style={styles.TXT_INPUT}
placeholder="Password"
/>
<View style={styles.auth}>
<Authentication_Button title={"Login"} backGroundColor={"#2c88d1"} textColor = {"#FFFFFF"} borderColor={"#2c88d1"}/>
<Authentication_Button title={"Signup"} backGroundColor={"#FFFFFF"} textColor = {"#2c88d1"} borderColor={"#2c88d1"}/>
</View>
<Text>- OR -</Text>
<Text>Sign in with </Text>
<SocialIcon
raised={true}
type='google'
style={{backgroundColor:"#2c88d1"}}
/>
<KeyboardAvoidingView style={styles.bottomView}>
<Image source={require('./assets/footLogin.png')} />
</KeyboardAvoidingView>
{/* </View> */}
</KeyboardAvoidingView>
)
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor:"#effdfe",
justifyContent:"center",
alignItems:"center",
padding:20
},
logo :{
width:150,
height:150,
resizeMode:'cover'
},
TXT_INPUT:{
marginBottom:10,
marginTop:10,
borderRadius:12,
borderWidth:1.4,
width:"85%",
paddingVertical:14,
backgroundColor:"#ffffff",
color:"#000000",
fontSize:18
},
auth:{
marginTop:10,
marginBottom:10,
width:"85%",
},
bottomView: {
marginTop:'5%',
position: 'absolute', //Here is the trick
bottom: 1, //Here is the trick
},
});
export default Login;
You can use KeyboardAvoidingView as a parent view. It will help you either your internal button or view is an absolute position
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.container}
>
</KeyboardAvoidingView>
So the issue has been resolved. The issue was that the footer image was basically on top ofthe text input fields so as soon I changed the positions, it started to work!

Download file using download link from api

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

<Image> url not showing for android React Native

I am using <Image> and <ImageBackground> with source:{{ uri: url }} inside my React Native project.
But the problem is an image is not showing inside Android simulator (But IOS simulator is fine)
This is my component
import React from 'react'
import {
Text, StyleSheet, ImageBackground, Image,
} from 'react-native'
import { Header } from 'react-navigation'
import { dimens } from '../../../services/variables'
const CustomHeader = ({ bgSrc }) => (
<ImageBackground
source={
bgSrc
? { uri: bgSrc }
: require('../../../assets/images/placeholder_image_bg_wide.png')
}
style={styles.header}
>
<Text style={styles.description}>First element</Text>
<Image source={{ uri: 'https://i.vimeocdn.com/portrait/58832_300x300.jpg' }} style={{ width: 200, height: 45, backgroundColor: 'red' }} />
<Text style={styles.description}>Second element</Text>
<Image source={{ uri: 'http://i.vimeocdn.com/portrait/58832_300x300.jpg' }} style={{ width: 200, height: 45 }} />
<Text style={styles.title}>Last element 1</Text>
</ImageBackground>
)
export default CustomHeader
const styles = StyleSheet.create({
header: {
minHeight: Header.HEIGHT,
height: dimens.header.height,
marginTop: dimens.header.marginTop,
paddingLeft: dimens.header.paddingLeft,
paddingBottom: dimens.header.paddingBottom,
backgroundColor: 'blue',
flexDirection: 'column-reverse',
},
title: {
...dimens.header.title,
},
description: {
...dimens.header.description,
},
})
I also already added permissions inside AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
This is the image of my both simulators
You will see that on IOS simulator <Image> is showing correctly but not on Android none images were show (Both http and https)
So how can i fix these and make Android simulator works, Thanks!
I have said this before in another question
https://stackoverflow.com/a/71263771/8826164
but there is an issue with Image component is that if first time initialize the component with source={{uri : 'some link'}} it may not work (at least not for me when I fetch image from HTTPS URL from Firebase storage). The trick is you have to trigger a change to source props like first you need to keep
source to source={undefined} and then change to source={{uri : 'some link'}}. And it seems like you have hard-coded URL for uri, so you might fall into the same issue as I did
Before :
<Image source={{ url: http://stitch2stitch.azurewebsites.net/assets/img/FileFormats/${result}.png}} style={{ height: 40, width: 40, }} />
After :
<Image source={{uri: http://stitch2stitch.azurewebsites.net/assets/img/FileFormats/${result}.png}} style={{ height: 40, width: 40, }} />
just change from url to uri works for me

How to resize video without changing it's aspect ratio?

constructor(props) {
super(props);
this.state = {
screenWidth: Dimensions.get('window').width,
heightScaled: null,
};
}
<View style={styles.videoView}>
<Video
source={video}
ref={(ref) => { this.player = ref }}
repeat={true}
resizeMode={"contain"}
style={{
width: this.state.screenWidth,
height: this.state.heightScaled,
}}
onLoad={response => {
const { width, height } = response.naturalSize;
const heightScaled = height * (this.state.screenWidth / width);
response.naturalSize.orientation = "horizontal";
this.setState({ heightScaled: heightScaled });
}}
/>
</View>
styles
videoView: {
flex: 1,
width: Dimensions.get('window').width,
height: 350
}
I'm fetching video from api and then using it in a video component using react-native-video. I don't know how I can resize my video to fit in a view without stretching the video.
Here is the result of the above code.
I don't want my video to cross the red line I marked in the image.
Please help me. I'm stuck on this problem from the past 3 days.
Adding one more <View /> inside the parent <View /> containing <Video /> will solve the overflow of the video.
<View style={styles.videoView}>
<Video
resizeMode={"contain"}
style={{
flex: 1
}}
/>
<View style={{flex: 1}}>
{/* Components after red line can be rendered here */}
</View>
</View>

Native-Base Picker does not work properly Android - Does not trigger function onValueChange

I'm using Picker component of Native-Base for my react-native application. On IOS everything is ok, whereas, on Android side I can not trigger function I added on onValueChange.
Is there anyone faced this issue before?
How did you fix it? I stuck here almost a day.
Here is my code.
<Picker style={{ width: 200, height: 40}}
iosHeader="Branch"
Header="Branch"
mode="dropdown"
textStyle={{color: 'white'}}
placeholder="Branch"
headerBackButtonText="Geri"
selectedValue={this.state.selectedBranch}
onValueChange={(value)=>this.onBranchSelected(value)}
>
{this.state.branches.map((branches, i)=>{
return(
<Picker.Item label={branches.address_line} value={branches.id} key={i}/>
);
}
)}
</Picker>
It does not call the function onBranchSelected on Android.
I tried your code and was working fine for me.
Pasting my code
import React, { Component } from "react";
import { Platform } from "react-native";
import { Container, Header, Title, Content, Button, Icon, Text, Right, Body, Left, Picker, Form } from "native-base";
export default class PickerExample extends Component {
constructor(props) {
super(props);
this.state = {
branches: [
{ address_line: 'address 1', id: 1 },
{ address_line: 'address 2', id: 2 },
{ address_line: 'address 3', id: 3 },
{ address_line: 'address 4', id: 4 },
{ address_line: 'address 5', id: 5 }],
selected1: 1
};
}
onBranchSelected(value) {
this.setState({
selectedBranch: value
});
}
render() {
return (
<Container>
<Header>
<Left>
<Button transparent>
<Icon name="arrow-back" />
</Button>
</Left>
<Body>
<Title>Picker</Title>
</Body>
<Right />
</Header>
<Content>
<Form>
<Picker
style={{ width: 200, height: 40 }}
iosHeader="Branch"
Header="Branch"
mode="dropdown"
textStyle={{ color: 'grey' }}
placeholder='Select branch'
headerBackButtonText='Geri'
selectedValue={this.state.selectedBranch}
onValueChange={(value) => this.onBranchSelected(value)}
>
{this.state.branches.map((branches, i) => {
return (
<Picker.Item label={branches.address_line} value={branches.id} key={i} />
);
}
)}
</Picker>
</Form>
</Content>
</Container>
);
}
}
Dependencies
"native-base": "2.3.5",
"react": "16.0.0",
"react-native": "0.50.0",
This is known issue with Picker. The issue is trying to use .map. I myself couldn't ever get map to work with Picker. The only thing I could find was an npm package called react-native-smart-picker which I was able to use a .map with. There are limitations.
And FYI I also tried other bootstrap frameworks and this is an issue with vanilla react-native.
Heres the link..
https://www.npmjs.com/package/react-native-smart-picker
Heres my github repo...
https://github.com/GavinThomas1192/motoMechanicMeeKanic/blob/master/App/Components/vehicleMakePicker.js
Heres my code where I implemented it.
<ScrollView>
<View style={{ flex: 1, marginTop: 20 }}>
{this.state.makes.length > 1 ?
<ScrollView>
<SmartPicker
expanded={this.state.expanded}
selectedValue={this.state.selectedMake}
label='Select Make'
onValueChange={this.handleChange.bind(this)}>
{
this.state.makes.map((ele) => {
return (<Picker.Item label={ele} value={ele}/>);
})
}
<Picker.Item label='Select Make' value='Toyota'/>
</SmartPicker>
<Button block onPress={() => this.props.vehicleMake(this.state.selectedMake)}>
<Text>Done</Text>
</Button>
</ScrollView> : <Spinner/>
}
</View>
</ScrollView>
Update to show how I handled no expandable button
<Content>
<Text>Vehicle Stats:</Text>
<Text>Year: {this.state.vehicleYear}</Text>
<Text>Make: {this.state.vehicleMake}</Text>
<Text>Model: {this.state.vehicleModel}</Text>
{this.state.vehicleYear === "" ? <VehicleYearPicker vehicleYear={this.yearPicked}/> : undefined}
{this.state.vehicleYear !== "" && this.state.vehicleMake === "" ?
<VehicleMakePicker pickedYear={this.state.vehicleYear} vehicleMake={this.makePicked}/> : undefined}
{this.state.vehicleModel === "" && this.state.vehicleMake !== "" ?
<VehicleModelPicker homeState={this.state} vehicleModel={this.modelPicked}/> : undefined}
</Content>

Categories

Resources