React native Image ' Warning: Failed prop type: Invalid prop `source` supplied to `Image`. ' - react-native

So this is my code
I already answered the question.
export const BigCard = ({Title, Image, Description}) => {
console.log(Image)
return(
<StyledBigCard>
<StyledImage source={{
uri: Image,
}}/>
<StyledStroke>
<StyledStrokeText>
<StyledPBigCard>{Description}</StyledPBigCard>
</StyledStrokeText>
<FontAwesomeIcon style={style.icon} size={ 22 } icon={faChevronRight} />
</StyledStroke>
</StyledBigCard>
)
};
this is were i import the images etc. it is set in PBS1Detail, its an object so when i go to PBS1Detail.Image i get the image
const db = firebase.firestore();
const [PBS1Detail, setPBS1Detail] = useState([]);
const [partnerLevel, setPartnerLevel] = useState('');
useEffect(()=> {
{/* DATABASE */}
db.collection('Track').get().then((snapshot) => {
let results = []
snapshot.docs.forEach(doc => {
results.push(renderTracks(doc))
}
)
setPBS1Detail(results)
});
then i push it all the way to the screen were i import Image
all my imports are correct, and the console.log() gives me the good url to the image.
now when i now reload the app it gives the error "Warning: Failed prop type: Invalid prop source supplied to Image."
then when i update the image component to
<StyledImage source={{uri: 'https://s3.eu-central-1.wasabisys.com/image-parttime-bijbelschool-jaar-1/Track1Module1Thumbnail.jpg'}}
and than save the changes it works
then when i update it to
<StyledImage source={{uri: Image}} />
and than save the changes it also works
so when i run it the first time it gives me this error than when i change it to an url and than change it back to the Image prop it works. but when i reload the app it gives me this error again.
how can i fix this?

The PBS1Detail is an empty array until you actually get the image data from Firestore.
So when the first render, I guess you are trying to pass undefined or some invalid values for the source prop.
How about you give a condition for the render part?
export const BigCard = ({Title, Image, Description}) => {
console.log(Image)
return(
<StyledBigCard>
{!!Image && (
<StyledImage source={{
uri: Image,
}}/>
)}
<StyledStroke>
<StyledStrokeText>
<StyledPBigCard>{Description}</StyledPBigCard>
</StyledStrokeText>
<FontAwesomeIcon style={style.icon} size={ 22 } icon={faChevronRight} />
</StyledStroke>
</StyledBigCard>
)
};

The problem is not my code above, what i did was that on my homescreen i sended wrong props to Image is send
Image={Require('../../assets/Image.png')}
thats why te error occurded. i have set it to
Image={'https://s3.eu-central-1.wasabisys.com/image-parttime-bijbelschool-jaar-1/Track1Module1Thumbnail.jpg'}
and it works perfectly!

Related

KeyboardAwareScrollView props innerRef scrollToEnd not working

I'm trying to call scrollToEnd() in a screen that uses https://github.com/APSL/react-native-keyboard-aware-scroll-view and I get the error:
"cannot read property 'props' of undefined".
My code looks like this:
let scroll
(at the beginning of the file)
Then, inside the return:
<KeyboardAwareScrollView innerRef={ref => { scroll = ref }}>
my scrollable code
</KeyboardAwareScrollView>
And then there is a button which has
onPress={() => scroll.props.scrolltoEnd()}
Clicking the button gives the error above, which makes me think I'm not using innerRef correctly? Do I need to use useRef instead at some point? Any help is appreciated, thanks!
on KeyboardAwareScrollView use React.useRef
const scrollRef = React.useRef(null);
<KeyboardAwareScrollView
ref={scrollRef}
....
And on your input, listen onContentSizeChange
<Input
onContentSizeChange={(e) => {
if (scrollRef && scrollRef.current) {
scrollRef.current?.scrollToEnd();
}
}}
/>
You must use innerRef instead of ref and it will work.
<KeyboardAwareScrollView
innerRef={(ref) => {
scrollRef.current = ref;
}}

TypeError: Cannot read property 'map' of undefined ? Jest / React Native

I have an image slider component to display images from my Firebase database as follows ,
import React from 'react';
import Swiper from 'react-native-swiper';
import { View, StyleSheet, Image } from 'react-native'
const ImageSlider = ({images}) => {
return (
<Swiper autoplayTimeout={5}
style={styles.wrapper}
showsButtons={false}
loadMinimal={true}
showsPagination={true}
paginationStyle={styles.paginationStyle}
activeDotStyle={styles.activeDotStyle}
dotStyle={styles.dotStyle}
loop={true} autoplay={true}
>
{images.map((data, index) => {
return (
<View key={index} style={styles.slider}>
<Image style={styles.itemImage} source={{ uri: data }} />
</View>
)
})}
</Swiper>
)
}
For test above component I used follwing test file ,
import React from 'react';
import renderer from 'react-test-renderer';
import ImageSlider from '../../../src/components/imageSlider/ImageSlider';
test('renders correctly', () => {
const tree = renderer.create(<ImageSlider />).toJSON();
expect(tree).toMatchSnapshot();
});
When I'm run npm test command and after I got following error
TypeError: Cannot read property 'map' of undefined
Can anyone help me to slove this problem , Thank you
In your test, you're creating an ImageSlider without any parameters:
<ImageSlider />
In ImageSlider, you try to map the property images:
images.map( //etc
Because you didn't pass in an images parameter/property, images is undefined when you try to map it. To solve, this pass in value for images in your test:
<ImageSlider images={YOUR_TEST_IMAGES_DATA}/>
The other option is to redesign ImageSlider so that it fails gracefully if images is undefined. But, then there wouldn't be much a point in doing the test (unless the test was to see what happens if no parameter is passed in)

React Native is there an attribute equals to alt on image component

Coming from reactjs i was expecting "alt" attribute on the image component that will show text in case the image could not be loaded.
I read the documentation here and the closest thing I found is the on error event.
Is there an attribute equal to alt in React Native image component? And what is the easiest way to replace your image with a default text if i don't have the alt attribute?
You can make such a component yourself, it requires a very minimal amount of code. Here's a basic example:
export default class AccessibleImage extends Component {
state = {
error : false
};
_onImageLoadError = (event) => {
console.warn(event.nativeEvent.error);
this.setState({ error : true });
}
render() {
const { source, alt, style } = this.props;
const { error } = this.state;
if (error) {
return (
<Text>{alt}</Text>
);
}
return (
<Image
accessible
accessibilityLabel={alt}
source={source}
style={style}
onError={this._onImageLoadError} />
);
}
}
This will show the provided alt if there was an error loading the image and also use that text as the accessibilityLabel for screen readers which is closer to web behaviour.
A better answer than the previous if using React Native 0.68+ is to include the alt attribute on an <Image> Component like so
<Image
style={styles.yourImageStyles}
source={{
uri: 'https://reactnative.dev/img/tiny_logo.png',
}}
alt={'Alternate text that will be read be screen readers'}
/>
Chatgpt said:
let displayImage;
try {
displayImage = <Image source={require('./secondImage.png')} />;
} catch (error) {
displayImage = <Text>Second Image not available</Text>;
}
and to use the image/text:
{displayImage}

React Native WebView onMessage and postMessage to get all web page

I don't really clear how to implement onMessage and postMessage, can I get whole web page but only from react native side.
I mean, I will inject this code using injectedJavaScript
var markup = document.documentElement.innerHTML
window.postMessage(markup)
and I will receive the result using onMessage. Is it posible cause so far I can't do that
yes you can do this all you to have to do is use window.postMessage("message") from your web-page that is going to load in WebView and you can see that message in onMessage prop.
Example:
class Test extends React.Component{
constructor(props){
super(props);
this.state:{
html:''
}
}
componentWillMount(){
this.setState({
html : `<html>
<head>
<script>
window.postMessage("Messga from webView")
</script>
</head>
<body><h1>Hello from webView</h1></body>
</html>`
})
}
render(){
return (
<View style={{flex: 1}}>
<WebView
ref={(reff) => {
this.webView = reff;
}}
source={{html: this.state.html}}
style={[styles.flex1, styles.padding5]}
onMessage={(event)=>{
let message = event.nativeEvent.data;
/* event.nativeEvent.data must be string, i.e. window.postMessage
should send only string.
* */
}}
onNavigationStateChange={(evt)=>{}}
onError={(e) => {
console.warn('error occured', e)
}}/>
</View>
)
}
}
I just added a sample html and rendered it in WebView, you can do the same in your page that you are going to load in WebView.
Or another solution is:
You can use injectedJavaScript or injectJavaScript props of WebView as described here.
postMessage is deprecated :: and now you have to use window.ReactNativeWebView.postMessage(data)
const injectedJavascript = `(function() {
window.postMessage = function(data) {
window.ReactNativeWebView.postMessage(data);
};
})()`;
for a full imagination of a component will be:
export const WebViewComponent = (props) => {
const webViewScript = `
setTimeout(function() {
window.ReactNativeWebView.postMessage(/*your pushed data back to onMessage 'event.nativeEvent.data'*/);
}, 2500);
true; // note: this is required, or you'll sometimes get silent failures
`;
return (
<WebView
source={{
uri: `https://example.com`,
}}
automaticallyAdjustContentInsets={false}
scrollEnabled={false}
onMessage={(event) => {
// do something with `event.nativeEvent.data`
}}
javaScriptEnabled={true}
injectedJavaScript={webViewScript}
domStorageEnabled={true}
style={{ width: "100%", height: /*webViewHeight*/ }}
/>
);
};
Actually
i was looking at the documentation since i use the injectJavascript function of the react native´s webview. And in here https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage , it says that for extensions we need to use a "*" as a property .
So it wouldn´t be like this "window.postMessage("Messga from webView")"
Instead it will need to be window.postMessage("Messga from webView","*") to work.

can't passing parameter to another screen React Native

i'm using react navigation and trying to send parameter from second screen to third screen
First Screen (App.js)
this.props.navigation.navigate('Index1',{userid1:this.state.studentsS});
Second Screen (Index.js)
this.props.navigation.navigate('MyDealOffer',{userid3:this.props.navigation.state.params.userid1});
when i check the value for (this.props.navigation.state.params.userid1) it's having the correct number
Third Screen(MyDealOffer.js)
componentDidMount(){
this.setState({
parmstudentid:this.props.navigation.state.params.userid3,
})
var x = this.props.navigation.state.params.userid3;
var url = 'http://***:82/wasily/MyDealOffer.php?
UserID=${this.props.navigation.state.params.userid3}'
fetch(url,
{method:"POST"}).then((response)=>response.json()).then((responseJson)=>{
var ds = new ListView.DataSource({rowHasChanged:(r1,r2)=>r1!=r2});
this.setState({
isLoading:false,
cloneStudent:ds.cloneWithRows(responseJson),
});
})
}
render() {
if(this.state.isLoading){
return(
<View><Text>Wait</Text></View>
)
}
return (
<View style={styles.container}>
<Text>User Details</Text>
<ListView
dataSource={this.state.cloneStudent}
renderRow={(rowData)=>
<Text>Username : {rowData.Price} , User ID:{rowData.Price} </Text>
}/>
</View>
`
output : "user details without any data"
========================But======================
when i change in the second screen the below line
this.props.navigation.navigate('MyDealOffer',{userid3:this.props.navigation.state.params.userid1});
to
this.props.navigation.navigate('MyDealOffer',{userid3:4});
it's showing correct data in the third screen
Try changing onPress={this.handle1Press} inside your TouchableOpacity to onPress={this.handle1Press.bind(this}