Here is what I am trying to do with React Native:
Get the image URL data from the database.
Check if the image exists in the storage.
If the image exists, render it. If not, render a placeholder image.
Basically, I declared a function to do steps 2&3 and put that as a source in the Image component. However, the Image component won't render any image, even if the target image exists in the storage with the URL.
What might be going on here? Here is the code that I am using. Don't see why this code won't work...Maybe a syntax error? What might be a fix/better way to do this?
//The function to check if the image actually exists and return placeholder if not
const checkImageURL = (url) => {
const placeholder_url='url_of_placeholder_image';
fetch(url)
.then(res => {
if(res.status == 404){
return placeholder_url;
}
else{
return url;
}
})
.catch(err=>{return placeholder_url})
}
//The way I declared the source for the image
<Image source={uri:checkImageURL(url)} style={style.mainImage}/>
Source prop for remote URL must be an object, so you need to add one more curly braces
<Image source={{uri:checkImageURL(url)}} style={style.mainImage}/>
More info about curly braces in props here
Related
My RN 0.62.2 app needs to automatically save page data just before the function component unmounts. The idea is that when the user close the page (detecting losing focus may not work here since user may zoom in image in modal screen), then the save (to backend server) is automatically triggered. Since it is function component, how to know when the component will unmount?
Here is the sample code of a function component shall do:
const MyCom = () => {
//do something here. ex, open gallery to upload image, zoon in image in `modal screen, enter input`
if (component will unmount) {
//save the data by sending them to backend server
}
}
The useEffect triggers with every rendering and will have performance issue if keep saving to backend server with each and every rendering. The auto save only happens once just before the component unmount. User may click Back or Home button to leave the page.
Yoı must use useEffect for componentWillUnmount in functional components.
const MyCom = () => {
//do something here. ex, open gallery to upload image, zoon in image in
useEffect(() => {
// Component Did Mount
return => {
// ComponentWillUnmount
}
},[])
return(/*Component*/)
}
I have a situation right now with my RN app, and I don't know how to tackle it.
I'm logging the user in through Facebook API, in our backend, we handle all the FB user data, and also, its profile picture that we crop to a certain size for performance purposes.
To do this, we run an async worker that will do the cropping, in the meantime, in the app we show a default user avatar with the app logo. But once the worker finished the task, the image isn't updated, not until I re-render the view, this re-render causes to run again "renderUserAvatar()" function which validates if the user has a profile picture or not. Which makes sense.
Now here's the help, how can I listen to this URL availability? So that whenever the Image is available, it re-renders?
At first, I thought about adding something like handling the Image's onError, by setting a setInterval, and trying to force a re-render, but that doesn't look very performant it rather sounds ugly.
Is there a clean way to handle this specific case-scenario?
This is my current renderUserAvatar function:
renderUserAvatar() {
const { userInfo } = this.props;
if (!_.isEmpty(userInfo) && userInfo.userPictures && userInfo.userPictures.length) {
const avatar = userInfo.userPictures.filter(pic => pic.isAvatar && pic.isEnabled);
if (avatar && avatar.length) {
const url = `${avatar[0].url}?height=${USER_AVATAR_HEIGHT}&width=${USER_AVATAR_WIDTH}`;
return <Thumbnail large style={ styles.userProfilePic } source={{uri: url}}/>;
}
}
return <Thumbnail large style={ styles.userProfilePic } source={ImageAssets['user-avatar']}/>
}
(Thumbnail is a NativeBase's component based on React-Native Image. So it would have all the Image methods and props too)
You could put your image into a state-variable.
At the first load (or if User-Image are not yet fetched) it is your Placeholder-Image.
If the async function runs on entering the screen and the images was fetched, replace the placeholder-image in the state with your new one.
The change of a state-variable will cause a re-render and this way, you'r image should appear.
I'm trying to build an app using react native with a firestore database. I'm fairly new to the react native framework (as well as working with firestore), so it's possible I might be trying to solve this problem the wrong way.
I have a database that works well and is already populated. For each user of this app, I'd like to add a map to their entry. I want to use this map to store some data about the user which they can fill out later.
Here's some code:
componentDidMount() {
this.readProfile(this.props.uid);
}
readProfile = (uid) => {
this.props.getProfile(uid).then((profile) =>
{
if(!profile.userMap)
{
profile.userMap = generateUserMap();
}
...
}
export const generateUserMap = function () {
var map = new Map();
SomeEnum.forEach((key, value) => {
map.set(key, false);
});
AnotherEnum.forEach((key, value) => {
map.set(key, false);
});
OneMoreEnum.forEach((key, value) => {
map.set(key, false);
});
return map;
};
...
<Input
value={this.state.profile.userMap[SomeEnum.Foo]}
onChangeText={(foo) => this.updateUserMap({ foo })}
/>
What I want this code to be doing is to read in the user's profile when I load the page. That part seems to be working fine. My next concern is to properly initialize the map object. The code doesn't seem to be properly initializing the map, but I'm not sure why. Here's why I say that:
TypeError: Cannot read property 'Foo' of undefined
With the stack trace pointing to my component's Connect() method.
Any help would be greatly appreciated.
EDIT: Apologies for the oversight, here is the updateUserMap function:
updateUserMap = (property) => {
const profile = Object.assign({}, this.state.profile, property);
this.setState({ profile });
}
So, as anyone who looks over this question can probably tell, I was doing a few things pretty wrong.
The error I'm getting referred specifically to that input block in my render method - this.state.profile.userMap was undefined at that point. I can guarantee that it won't be undefined if I do my check within the render method but before I'm accessing the userMap. Because of how the lifecycle methods work in react native, ComponentDidMount wouldn't be called before my render method would.
My enum code also wouldn't work. I changed that to a simple for loop and it works like a charm.
Here's my updated code:
render() {
if(!this.state.profile.userMap)
{
this.state.profile.userMap = generateUserMap();
}
I am trying to add a custom image source to the attribute iconButtonCenter in the React Native library named react-native-circle-button.
https://github.com/dwicao/react-native-circle-button
According to the documentation, iconButtonCenter is of type enum, so I imported the icon and then passed it in directly where I create my CircleButton object. It does not yell as if it is a number or string, yet I still am not 100% sure it is technically of type enum. I know for a fact it is finding the image in the right path. I also know that it is doing something, because the default image is no longer observable on the app, it just no longer has an icon. I am not getting any compilation errors or warning, yet I still do not see the icon appear over the button as it should. How do I fix this?
Here is the render within my component that allows circle button's to be draggable. I also went ahead and put my import at the top so you can see how this was stored.
import letterA from '../assets/letters/alpha-a.svg';
render() {
let { pan } = this.state;
let [translateX, translateY] = [pan.x, pan.y];
let moveableStyle = {transform: [{translateX}, {translateY}]};
const panStyle = {
transform: this.state.pan.getTranslateTransform()
}
return (
<Animated.View
{...this._panResponder.panHandlers}
style={[moveableStyle, panStyle]}>
<CircleButton iconButtonCenter={letterA} /> <--- Here is the image source reference.
</Animated.View>
);
}
The CircleButton component should successfully have the image fed to it and remain centered over the button even when dragged along the string.
Problem was the picture format was an .svg, converting the icons to .png worked like a charm!
I'm trying to pass the data I have received from scanning a barcode. I'm able to print the data using JSON.stringify(data) and the data is being passed but I just can't seem to display it.
Passing the data successfully with:
_handleBarCodeRead = data => {
Alert.alert(
'Scan successful!',
JSON.stringify(data)
);
const { navigate } = this.props.navigation;
navigate('KnownProduct', {data})
};
Attempting to render the data on this page:
render(){
const { navigate } = this.props.navigation;
return(
<View style={styles.container}>
<Text>{this.props.navigation.state.params.data.toString}</Text>
</View>
);
I know the navigation works correctly because if I hard-code the value the screen does navigate after scanning a barcode and display the hard-coded value. However, I think I'm trying to call the data incorrectly with: this.props.navigation.state.params.data.toString but having no luck figuring out how to display the passed data.
Any react native experts able to help a newbie?
OK.... So I figured it out... thanks to one commenter who pointed out I should pass the data like so:
navigate('KnownProduct', {data: data})
And then what was missing in the redirection page was:
<Text>{this.props.navigation.state.params.data.data}</Text>
data.data got me!
Try this :
navigate('KnownProduct', {data:JSON.stringify(data)})
AND
<Text>{this.props.navigation.state.params.data}</Text>
try this
navigate('KnownProduct', {data:data.data})
<Text>{this.props.navigation.getParam('data')}</Text>