Not able to fetch image from API in React Native - javascript

I am a beginner on React Native and was working on an app that fetches text and images from my API and displays it on the screen. The text is displayed but the image is not displayed. No errors. I have only one main file : App.js with the API call being
https://www.teanewsnetwork.com/api/fetcharticles.php?code=Me*z6Pcw9e1$CQ)YWgMlFe%nv(Hq)lhw&starting=0&limit=20
App.js :
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
import React, { Component } from 'react';
import {
View,
Text,
ActivityIndicator,
ScrollView,
StyleSheet,
Image,
} from 'react-native';
import Img from 'react-image';
let li = 'https://www.teanewsnetwork.com/profileicons/';
let bean = 'azure.jpg';
export default class App extends Component {
state = {
loading: true,
error: false,
posts: [],
};
componentWillMount = async () => {
try {
const response = await fetch(
'https://www.teanewsnetwork.com/api/fetcharticles.php?code=Me*z6Pcw9e1$CQ)YWgMlFe%nv(Hq)lhw&starting=0&limit=40'
);
const posts = await response.json();
this.setState({ loading: false, posts });
} catch (e) {
this.setState({ loading: false, error: true });
}
};
renderPost = ({ id, title, content, authorimage, authorname }, i) => {
let b = { authorname };
return (
<View style={styles.postContent}>
<Text>{authorname}</Text>
<Image
source={{
uri: 'https://teanewsnetwork.com/profileicons/',
}}
style={{ width: 40, height: 40 }}
/>
<Text style={styles.postauthor}>{title}</Text>
<Text style={styles.postBody}>{content}</Text>
</View>
);
};
render() {
const { posts, loading, error } = this.state;
if (loading) {
return (
<View style={styles.center}>
<ActivityIndicator animating={true} />
</View>
);
}
if (error) {
return (
<View style={styles.center}>
<Text>Failed to load posts!</Text>
</View>
);
}
return (
<ScrollView style={styles.container}>
{posts.map(this.renderPost)}
</ScrollView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
postauthor: {
flex: 1,
borderBottomWidth: 1,
borderBottomColor: '#EEE',
paddingVertical: 25,
paddingRight: 15,
},
postContent: {
flex: 1,
borderBottomWidth: 1,
borderBottomColor: '#EEE',
paddingVertical: 25,
paddingRight: 15,
left: 10,
},
postBody: {
marginTop: 10,
fontSize: 12,
color: 'lightgray',
left: 10,
},
center: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
I want to display my images below every name which are to be taken from the link
www.teanewsnetwork.com/profileicons/{{authorimage}}
Where {{authorimage}} is given in the API. But this doesn't seem to work.
Thanks is advance!

You can use template literals in JavaScript. This will append the authtorimage to the end of the string.
<Image
source={{
uri: `https://teanewsnetwork.com/profileicons/${authorimage}`,
}}
style={{ width: 40, height: 40 }}/>
Template literals are enclosed by the back-tick (```) (grave accent) character instead of double or single quotes. Template literals can contain placeholders. These are indicated by the dollar sign and curly braces (${expression}). The expressions in the placeholders and the text between them get passed to a function.

You are doing it very correctly except in two places which I have pointed below:
- While importing the react native components you are also doing:
import Img from 'react-image';
This is unnecessary as react native itself provides Image components.
- Also, you need to pass value of authorimage in source of the image as:
<Image
source= {{
uri: `https://teanewsnetwork.com/profileicons/${authorimage}`,
}}
style={{height: 40, width: 40}}
/>
Here, is the link of working snack.
If you want to learn more about how images works in react native, you can visit this link.

Related

React Native module fails to load because of a single function that is not even invoked. Error : 'AppRegistry.registerComponent'

So I'm having some bundling problem with a single function that is not even invoked. const { status } = await BarCodeScanner.requestPermissionsAsync(); The function should be invoked when the QR code is scanned and the string information gets parsed and saved to a SQLite database. There is something wrong with bundling the app. I tried to set a setTimeOut at the root but to no avail. Here is the error That I'm getting:
ERROR TypeError: undefined is not an object (evaluating '_Splash.default.TABLE_REFERENCE')
LOG Running "main" with {"rootTag":91,"initialProps":{}}
ERROR Invariant Violation: "main" has not been registered. This can happen if:
* Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
* A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called.
Here is the actual screen. nothing fancy really.
import { StackScreenProps } from "#react-navigation/stack";
import { BarCodeScanner, BarCodeScannerResult } from "expo-barcode-scanner";
import AsyncStorage from "#react-native-async-storage/async-storage";
import React, { useEffect, useState } from "react";
import {
Alert,
StyleSheet,
Text,
useWindowDimensions,
View,
ScrollView,
} from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
import { BackBar } from "../../components/BackBar";
import { useDispatch } from "react-redux";
import {
IntroScreen,
IntroStackParamList,
} from "../../navigation/intro/StackUtil";
import { EnumFonts } from "../../types/enums/fonts.enum";
import addSplashUriToDatabase from "../../database/addSplashUriToDatabase";
import { setStarter } from "../../store/starter/actions";
import { Camera } from "expo-camera";
interface Props
extends StackScreenProps<IntroStackParamList, IntroScreen.ScanQR> {}
const ScanQRScreen: React.FC<Props> = (props) => {
const [hasPermissions, setHasPermissions] = useState(false);
const [scanned, setScanned] = useState(false);
const [processing, setProcessing] = useState(false);
const { width, height } = useWindowDimensions();
const dispatch = useDispatch();
useEffect(() => {
(async () => {
const { status } = await BarCodeScanner.requestPermissionsAsync();
setHasPermissions(status === "granted");
})();
}, []);
const handleBarCodeScanned = async ({ type, data }: BarCodeScannerResult) => {
setScanned(true);
console.log(
`Bar code with type ${type} and data ${data} has been scanned!`
);
try {
const success = await addSplashUriToDatabase(data);
if (success) {
// Navigate to other screen
dispatch(setStarter(false));
try {
const value = await AsyncStorage.setItem("#starter", "true");
if (value !== null) {
// value previously stored
// setStarter("false");
}
} catch (e) {
// error reading value
}
}
} catch (error) {
console.error(error);
Alert.alert(
"Fail to scan QR code",
"Please let us know, this could caused by invalid participant names.",
[
{
text: "OK",
},
// {text: 'Report Bug', onPress: failOnScan},
],
{ cancelable: true }
);
}
};
return (
<SafeAreaView style={{ flex: 1 }}>
<ScrollView style={{ flex: 1, padding: "5%" }}>
<BackBar goBackFunction={props.navigation.goBack} />
<View
style={{ flex: 0.3, justifyContent: "space-evenly", marginTop: 30 }}
>
<Text
style={{
fontFamily: EnumFonts.BOLD,
fontSize: 30,
marginVertical: 10,
}}
>
Scan a Splash code
</Text>
<Text
style={{
fontFamily: EnumFonts.REGULAR,
fontSize: 20,
marginVertical: 10,
}}
>
Line up the Splash code in the red square. Ensure the other phone
has its screen brightness at maximum setting.
</Text>
</View>
<View style={{ flex: 0.6, justifyContent: "space-around" }}>
{hasPermissions && (
<>
<View
style={{
width: width * 0.8,
borderWidth: 5,
borderColor: scanned ? "green" : "red",
backgroundColor: "black",
alignSelf: "center",
}}
>
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={{
width: "100%",
height: height * 0.45,
borderWidth: 1,
borderColor: "red",
}}
/>
</View>
<Text
style={{
fontFamily: EnumFonts.REGULAR,
fontSize: 18,
textAlign: "center",
marginTop: 15,
}}
>
The square will turn green to indicate a successful scan
position
</Text>
</>
)}
{!hasPermissions && (
<Text
style={{
fontFamily: EnumFonts.MEDIUM,
fontSize: 20,
textAlign: "justify",
}}
>
Please allow us to use camera to scan qr
</Text>
)}
</View>
</ScrollView>
</SafeAreaView>
);
};
export default ScanQRScreen;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
});

TypeError: undefined is not an object (evaluating 'stateText.length')

I am using react-native-google-places-autocomplete for a filter menu on a project. While I am inputting text into the <GooglePlacesAutocomplete/> object I want to track the text input with a state variable called 'address'. To do that I used a predefined function preProcess (ideally I would use onChangeText, but <GooglePlacesAutocomplete/> does not support it). Fortunately the state variable does update when input text is changed; however, after it updates, I receive a TypeError: undefined is not an object (evaluating 'stateText.length'). I've read every blog and stack overflow chain dealing with similar errors and haven't found why this error pops up with my specific application. Any help would be greatly appreciated.
import React, { useState, useEffect } from "react";
import {View, Text} from "react-native";
import Screen from "../../../../components/Screen";
import styles from "./LocationStyles";
import colors from "../../../../config/colors";
import { GooglePlacesAutocomplete } from "react-native-google-places-autocomplete";
import Geocoder from "react-native-geocoding";
import SuggestionRow from "./SuggestionRow";
function LocationScreen(props) {
const [address, setAddress] = useState("");
Geocoder.init("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", { language: "en" });
useEffect(() => {
console.log(`address is ${address}`);
}, [address]);
return (
<Screen style={styles.screen}>
<View style={{ marginTop: 25 }}>
<Text style={{ height: 25, fontSize: 14 }}>Street*</Text>
<View style={{ height: 100, position: "relative", zIndex: 10 }}>
<GooglePlacesAutocomplete
preProcess={(value) => setAddress(value)}
minLength={5}
debounce={200}
enablePoweredByContainer={false}
onPress={(data, details = null) => {
Geocoder.from(data.description)
.then((json) => {
var location = json.results[0].geometry.location;
})
.catch((error) => console.warn(error));
setAddress(`${data.terms[0].value} ${data.terms[1].value}`);
}}
styles={{
textInputContainer: {
borderWidth: 1,
borderRadius: 10,
overflow: "hidden",
paddingTop: 3,
borderColor: colors.transparentPrimary,
height: 45,
},
textInput: {
height: 38,
color: colors.black,
fontSize: 14,
},
}}
query={{
key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
language: "en",
types: "address",
fields: "geometry",
components: "country:us",
}}
renderRow={(item) => <SuggestionRow item={item} />}
/>
</View>
<Text style={{ color: colors.medium, fontSize: 10, marginTop: -50 }}>
e.g. 100 Larch Ave
</Text>
</View>
</Screen>
);
}
export default LocationScreen;

React Native Mapbox-gl Error Coordinaes must conatin number, I have typecasted the coordinates but its still giving same error. How can I fix it?

I am facing this error. The coordinates stored in the database of App are in String. I have typecasted the String coordinates to Number but still facing this error.
This is my Map Code
import { View, Text, StyleSheet } from "react-native";
import MapView, { Marker } from "react-native-maps";
import MapboxGL from "#react-native-mapbox-gl/maps";
MapboxGL.setConnected(true);
const Map = ({ data, locationData }) => {
console.log(data);
useEffect(() => {
MapboxGL.setTelemetryEnabled(false);
}, []);
const [startCoordinate, setStartCoordinate] = useState([
Number(locationData.startLong),
Number(locationData.startLat),
]);
const [endCoordinate, setEndCoordinate] = useState([
Number(locationData.endLong),
Number(locationData.endLat),
]);
const renderMarkers = data.map((marker, index) => {
return (
<MapboxGL.PointAnnotation
coordinate={[
Number(marker.longitude),
Number(marker.latitude),
]}
// key={index}
>
<View
style={{
height: 30,
width: 30,
backgroundColor: "red",
borderRadius: 50,
borderColor: "#fff",
borderWidth: 3,
}}
/>
</MapboxGL.PointAnnotation>
);
});
return (
<View style={styles.page}>
<View style={(StyleSheet.absoluteFillObject, styles.container)}>
<MapboxGL.MapView style={styles.map}>
<MapboxGL.Camera zoomLevel={7} centerCoordinate={startCoordinate} />
<MapboxGL.PointAnnotation coordinate={startCoordinate} />
{renderMarkers}
<MapboxGL.PointAnnotation coordinate={endCoordinate} />
</MapboxGL.MapView>
</View>
</View>
);
};
const styles = StyleSheet.create({
page: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F5FCFF",
marginBottom: 50,
},
container: {
height: 300,
width: "100%",
backgroundColor: "tomato",
},
map: {
flex: 1,
},
});
export default Map;
In the above code you can check that I have typecasted the String to Number but still facing the same error coordinates must contain numbers
Thanks in Advance
Use geocoding for this purpose.

React Native and Firebase Real Time Database

I am having 2 problems using React Native and Firebase Real Time Database.
When I add something to the list with the text input, all the list itens are duplicated except the item that I just added, this problem is only solved when I refresh the app screen.
When I remove something from firebase dashboard or other client, the list is not updated real time.
import React, {useState, Component} from 'react';
import {
Text,
View,
Switch,
StyleSheet,
FlatList,
TextInput,
Button,
TouchableOpacity,
SafeAreaView,
VirtualizedList,
} from 'react-native';
import database from '#react-native-firebase/database';
class MenuBreakFastScreen extends React.Component {
state = {newItem: ''};
state = {itens: []};
componentDidMount() {
let dbRef = database().ref('/cafe/itens/');
this.listenerFirebase(dbRef);
}
listenerFirebase(dbRef) {
dbRef.on('value', dataSnapshot => {
const newItens = JSON.parse(JSON.stringify(this.state.itens));
dataSnapshot.forEach(child => {
newItens.push({
name: child.val().name,
key: child.key,
});
this.setState({itens:newItens});
});
});
}
addItem() {
if (this.state.newItem === '') {
return;
}
database().ref('/cafe/itens/').push({
name: this.state.newItem,
});
this.setState({
newItem: '',
});
}
render() {
const {itens} = this.state;
const {newItem} = this.state;
const renderItem = ( {item}) => {
return(
<ItemAsset title={item.name}/>
);
}
return (
<SafeAreaView
style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<FlatList
data={itens}
renderItem={renderItem}
keyExtractor={item => item.key}
/>
<SafeAreaView style={{flexDirection: 'row'}}>
<TextInput
style={styles.input}
onChangeText={text =>
this.setState({
newItem: text,
})
}
value={newItem}
/>
<TouchableOpacity style={styles.Botao} onPress={() => this.addItem()}>
<Text style={styles.BotaoTexto}>+</Text>
</TouchableOpacity>
</SafeAreaView>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
texto: {
fontSize: 35,
},
input: {
color: '#000',
fontSize: 22,
borderWidth: 1,
flex: 8,
margin: 10,
},
BotaoTexto: {
color: '#fff',
fontSize: 22,
},
Botao: {
backgroundColor: '#000',
marginTop: 10,
padding: 10,
flex: 1,
alignItems: 'center',
margin: 10,
},
ListaContainer: {
flexDirection: 'row',
backgroundColor: '#000',
flex: 1,
},
item: {
backgroundColor: '#000',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
flexDirection: 'row',
},
title: {
color: '#ffff',
fontSize: 32,
},
});
const ItemAsset = ( {title} ) => {
return(
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
}
export default MenuBreakFastScreen;
When you are listen for real time changes on real-time database it will send all the items with snapshot when any data is changed. That happens because you are listen for whole list, not only for a single item. Therefore you do not need to get the current list from state. You just have to set the state with retrieved data.
listenerFirebase(dbRef) {
dbRef.on('value', dataSnapshot => {
const newItens = []; // This should be initially empty array. That's all.
dataSnapshot.forEach(child => {
newItens.push({
name: child.val().name,
key: child.key,
});
});
this.setState({itens:newItens});
});
}
After correcting this part the error you got when removing data will be also resolved.

TypeError: undefined is not a function (near '...currencyFilter.map...')

I'm quite new to react native and trying to set up a search bar with search functionality. I'm trying to set it up where the list updates with each letter typed. The data is displayed fine but the error occurs when I try and type something into the search bar.
Full Error Message
https://ibb.co/Zd5hB52
Here is the file that is having issues
import { StyleSheet, Text, View, Button, StatusBar, ScrollView, TextInput } from "react-native";
import Icon from 'react-native-vector-icons/Ionicons';
import datas from "../components/CurrencyData"
import FavouritesList from "../components/FavouritesList";
const AddToFavourites = () => {
const state = {
datas: datas,
filter: datas
}
const [currencyFilter, setSearch] = useState(state.filter)
const getFlags = () => {
return currencyFilter.map(data => {
return <FavouritesList detail={data} key={data.id}/>
})
}
const searchCurrencies = (searchFor) => {
setSearch({
filterCurrency: datas.filter(i=>
i.name.toLowerCase().includes(searchFor.toLowerCase),
),
});
}
return (
<View style={styles.container}>
<View style= {styles.action}>
<Icon name="search" size={25}/>
<TextInput
style= {{flex: 1}}
placeholder= "Search..."
underlineColorAndroid="transparent"
onChangeText= {text => {searchCurrencies(text)}}
/>
</View>
<ScrollView>
<StatusBar backgroundColor="#1E90FF" barStyle="light-content"/>
{getFlags()}
</ScrollView>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
action: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
borderWidth: 2,
height: 50,
borderRadius: 30,
paddingLeft: "4%",
paddingRight: "4%",
margin: "3%"
},
})
export default AddToFavourites;```
[1]: https://i.stack.imgur.com/kWkHo.png
with hooks you don't pass the state object like setState, you just pass the new value
change
setSearch({
filterCurrency: datas.filter(i => i.name.toLowerCase().includes(searchFor.toLowerCase)),
});
to
setSearch( datas.filter(I =>i.name.toLowerCase().includes(searchFor.toLowerCase)));

Categories