React Native : Warning: Failed prop type: Invalid prop `coordinate` of type `number` supplied to `MapMarker`, expected `object` - react-native

I'm building my first app, a city guide app.
I'm still very new to React Native and I'm having a problem with react-native-maps (I think).
I'm trying to get the markers that show up on the map to come from my database via Axios queries
This is my Axios :
import axios from 'axios';
// URL API BASE
const APIURL = 'http://10.22.101.55:5000/api';
// RECUPERATION DES RESTAURANTS
export const getAllRestaurant = (nom, adresse, ville, cp, telephone, email, latitude, longitude ) => axios.get(`${APIURL}/restaurant`, {
nom: nom,
adresse: adresse,
ville: ville,
cp: cp,
telephone: telephone,
email: email,
latitude: latitude,
longitude: longitude
});
I had to change the URL of my call otherwise I received a Network Error type error
(Localhost -> 10.22.101.55)
My page where I call Axios :
import React, { useEffect } from 'react';
import { View, StyleSheet } from 'react-native';
import MapView, { Marker } from 'react-native-maps';
// Récupération des données
import {getAllRestaurant} from '../service/emplacements'
export default function AccueilScreen() {
// RECUPERATION DES RESTAURANTS
const [restaurants, setRestaurants] = React.useState([])
const LesRestaurants = () => [
getAllRestaurant().then(response => {
setRestaurants(response.data);
console.log(response);
}).catch(err => console.log('API :' + err))
]
// CHARGEMENT DES RESTAURANTS
useEffect(() => {
LesRestaurants()
},[])
return (
<View style={styles.container}>
<MapView
scrollEnabled={false}
rotateEnabled={false}
zoomEnabled={false}
minZoomLevel={0}
maxZoomLevel={13}
style={styles.map}
region={{
latitude: 49.4826616,
longitude: 1.7245633,
latitudeDelta: 0.015,
longitudeDelta: 0.0121,
}}
>
{restaurants.map((restaurant) => (
<Marker
key={restaurant.id}
coordinate={restaurant.latitude, restaurant.longitude}
title={restaurant.nom}
/>
))}
</MapView>
</View>
);
}
const styles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
height: '100%',
width: '100%',
justifyContent: 'flex-end',
alignItems: 'center',
},
map: {
...StyleSheet.absoluteFillObject,
},
});
And this what I got in the console :
Object {
"config": Object {
"adapter": [Function xhrAdapter],
"data": undefined,
"headers": Object {
"Accept": "application/json, text/plain, */*",
},
"maxBodyLength": -1,
"maxContentLength": -1,
"method": "get",
"timeout": 0,
"transformRequest": Array [
[Function transformRequest],
],
"transformResponse": Array [
[Function transformResponse],
],
"url": "http://10.22.101.55:5000/api/restaurant",
"validateStatus": [Function validateStatus],
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
},
"data": Array [
Object {
"adresse": "17 Rue de la France",
"cp": 76220,
"createdAt": "2021-05-10T07:41:25.000Z",
"email": "lerestaurant#gmail.com",
"id": 1,
"latitude": 49.4813,
"longitude": 1.73745,
"nom": "Le Restaurant",
"telephone": "0685459547",
"updatedAt": "2021-05-10T07:41:25.000Z",
"ville": "Gournay",
},
],
"headers": Object {
"cache-control": "public, max-age=0",
"connection": "keep-alive",
"content-length": "268",
"content-type": "application/json; charset=utf-8",
"date": "Mon, 10 May 2021 08:14:35 GMT",
"etag": "W/\"10c-flj/WYuf2hJDQ4N+xG++sHgKueQ\"",
"keep-alive": "timeout=5",
"x-powered-by": "Express",
},
"request": XMLHttpRequest {
"DONE": 4,
"HEADERS_RECEIVED": 2,
"LOADING": 3,
"OPENED": 1,
"UNSENT": 0,
"_aborted": false,
"_cachedResponse": undefined,
"_hasError": false,
"_headers": Object {
"accept": "application/json, text/plain, */*",
},
"_incrementalEvents": false,
"_lowerCaseResponseHeaders": Object {
"cache-control": "public, max-age=0",
"connection": "keep-alive",
"content-length": "268",
"content-type": "application/json; charset=utf-8",
"date": "Mon, 10 May 2021 08:14:35 GMT",
"etag": "W/\"10c-flj/WYuf2hJDQ4N+xG++sHgKueQ\"",
"keep-alive": "timeout=5",
"x-powered-by": "Express",
},
"_method": "GET",
"_perfKey": "network_XMLHttpRequest_http://10.22.101.55:5000/api/restaurant",
"_requestId": null,
"_response": "[{\"id\":1,\"nom\":\"Le Restaurant\",\"adresse\":\"17 Rue de la France\",\"ville\":\"Gournay\",\"cp\":76220,\"telephone\":\"0685459547\",\"email\":\"lerestaurant#gmail.com\",\"latitude\":49.4813,\"longitude\":1.73745,\"createdAt\":\"2021-05-10T07:41:25.000Z\",\"updatedAt\":\"2021-05-10T07:41:25.000Z\"}]",
"_responseType": "",
"_sent": true,
"_subscriptions": Array [],
"_timedOut": false,
"_trackingName": "unknown",
"_url": "http://10.22.101.55:5000/api/restaurant",
"readyState": 4,
"responseHeaders": Object {
"Cache-Control": "public, max-age=0",
"Connection": "keep-alive",
"Content-Length": "268",
"Content-Type": "application/json; charset=utf-8",
"Date": "Mon, 10 May 2021 08:14:35 GMT",
"ETag": "W/\"10c-flj/WYuf2hJDQ4N+xG++sHgKueQ\"",
"Keep-Alive": "timeout=5",
"X-Powered-By": "Express",
},
"responseURL": "http://10.22.101.55:5000/api/restaurant",
"status": 200,
"timeout": 0,
"upload": XMLHttpRequestEventTarget {},
"withCredentials": true,
},
"status": 200,
"statusText": undefined,
}
And the error message in the console + the error display
Warning: Failed prop type: Invalid prop coordinate of type number
supplied to MapMarker, expected object.
For me, the error is made because of the coordinate that I give to <Marker/>
Thanks in advance for your help and your time !
EDIT : The error is truly coming from coordinate, when I give manually the latitude and longitude, everything is working just fine.

The solution was to change :
coordinate={restaurant.latitude, restaurant.longitude}
to
coordinate={{latitude: restaurant.latitude, longitude: restaurant.longitude}}
the error was due to my syntax which was bad.
I was not giving latitude and longitude correctly to the coordinate prop.
And Coordinate cannot be 'null' or 'undefine'.

Related

Expo Camera FaceDetector Landmark Points

In expo-face-detector I have added detectLandmarks as below in Camera
<Camera
style={{ flex: 1 }}
type='front'
onFacesDetected = {faceDetected}
FaceDetectorSettings = {{
mode: FaceDetector.Constants.Mode.accurate,
detectLandmarks: FaceDetector.Constants.Landmarks.all,
runClassifications: FaceDetector.Constants.Classifications.all,
minDetectionInterval: 5000,
tracking: false
}}
>
but data that seems to be print on console.log(faces) within faceDetected function is below only. How to get coordinate of landmraks such as rightEyePosition, leftEyePosition etc as a part of output
object {
"faces": Array [
Object {
"bounds": Object {
"origin": Object {
"x": 68.6222222222222,
"y": 431.6488888888889,
},
"size": Object {
"height": 339.62222222222226,
"width": 220.44444444444446,
},
},
"faceID": -1,
"rollAngle": 0.12390166521072388,
"yawAngle": 0.6850103139877319,
},
],
}
You can try:
detectLandmarks: FaceDetector.Constants.Landmarks.none,
const faceDetected = (faces) => {
console.log(faces)
}

Axios get response is not carried over into state [Native React]

first question here.
when i try to run this, it does fetch data in the response.data, but that data is not set into state to be passed through as prop to another page and it always stays [Object object] or [undefined] & i have no clue what's going wrong
state = {
APiData: {},
userInput: "cheese",
onCall: false
}
findFood = () => {
let self = this;
let userInput = this.state.userInput.toLowerCase();
let url = "https://api.spoonacular.com/recipes/search?query=" + userInput + "&number=1&apiKey="+apiKey;
axios.get(url)
.then(function (response) {
console.log(response.data); //get's data
self.setState({APIdata: response.data});
})
.catch(function (error) {
console.log(error)
});
}
renderbody = () => {
console.log(this.state.APIdata) //this thing, is undefined
// return (<SearchBody data={this.state.APIdata} key={apiKey}/>)
}
this is the data in response.data
"baseUri": "https://spoonacular.com/recipeImages/",
"expires": 1585843318293,
"isStale": false,
"number": 1,
"offset": 0,
"processingTimeMs": 437,
"results": Array [
Object {
"id": 215435,
"image": "three-cheese-pizza-for-cheese-lovers-215435.jpg",
"imageUrls": Array [
"three-cheese-pizza-for-cheese-lovers-215435.jpg",
],
"readyInMinutes": 45,
"servings": 8,
"title": "Three-Cheese Pizza (For Cheese Lovers)",
},
],
"totalResults": 855,
}
Object {
"baseUri": "https://spoonacular.com/recipeImages/",
"expires": 1585843318293,
"isStale": false,
"number": 1,
"offset": 0,
"processingTimeMs": 437,
"results": Array [
Object {
"id": 215435,
"image": "three-cheese-pizza-for-cheese-lovers-215435.jpg",
"imageUrls": Array [
"three-cheese-pizza-for-cheese-lovers-215435.jpg",
],
"readyInMinutes": 45,
"servings": 8,
"title": "Three-Cheese Pizza (For Cheese Lovers)",
},
],
"totalResults": 855,
}
You are not using state. Your state needs to be inside your constructor
constructor(props) {
super(props);
this.state = {
APiData: {},
userInput: "cheese",
onCall: false
}
}
Then, you just need to call this.setState({ APIdata: response.data });
I would recommend you to use react-redux to get data using this.props.

React Native fetch() not outputting body in console log

I am using fetch() to get some data from an API. When testing in Postman the data is returned successfully as JSON. However, when testing from react native app on android I get a text/html response, not sure why. How can I view the body of the response from the text in console.log() to debug? When I do console.log(resp) I can not see the body.
const response = await fetch('https://web.com/api/usersignup', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
})
.then(resp => {
this.setState({spinner: false});
console.log(resp);// output in console is pasted under this code
return resp.text();
//return resp.json();
})
.then((responseJson) => {
console.log(responseJson);
})
.catch(error => {
this.setState({spinner: false});
Alert.alert('Error', error.message);
throw error;
});
Output I get in Metro Builder when using console.log(). Does not include body.
Response {
"_bodyBlob": Blob {
"_data": Object {
"blobId": "63acc7d8-bd8a-4dd7-b33b-f0e4f202f97e",
"offset": 0,
"size": 0,
},
},
"_bodyInit": Blob {
"_data": Object {
"blobId": "63acc7d8-bd8a-4dd7-b33b-f0e4f202f97e",
"offset": 0,
"size": 0,
},
},
"headers": Headers {
"map": Object {
"cache-control": "public, max-age=0",
"connection": "keep-alive",
"content-length": "0",
"content-type": "text/html; charset=UTF-8",
"date": "Sat, 09 Nov 2019 21:06:05 GMT",
"server": "Apache",
"x-ratelimit-limit": "60",
"x-ratelimit-remaining": "59",
},
},
"ok": true,
"status": 200,
"statusText": undefined,
"type": "default",
"url": "https://web.com/api/usersignup",
}
You cannot print the body until the promise of first then is finished.
I made an example with your code: https://snack.expo.io/#egizas/fetch-print-body
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
//body: JSON.stringify(formData)
})
.then(resp => {
console.log('Printing out not json');
console.log(resp);
return resp.json();
})
.then((responseJson) => {
console.log('Printing out json');
console.log(responseJson);
})
.catch(error => {
this.setState({spinner: false});
Alert.alert('Error', error.message);
throw error;
});
Just replace the endpoint and provide correct header.

RNPickerSelect trying to display selection from mapping data of objects in an array

I am using RNPickerSelect from the library "react-native-picker-select", but cant seem to display the selection by mapping objects of an array stored in one of my state.
I tried using the same way to map objects of an array like how I would when I'm trying to display the data by wrapping in simple components but I'm getting an "Type Error. undefined is not an object (evaluating this.state.selectedItem.label".
I have declared and initialize bankResponseArray : [] within my react native class. And the API call to fetch data was successful, the state "bankResponseArray" was inserted with the data of
[
Object {
"__v": 0,
"_id": "5cb411e06f34961204003b79",
"bank_code": "RHB",
"country": "5cb04a7e23479e39e495f2b6",
"created_date": "2019-04-15T05:08:48.769Z",
"name": "RHB",
"status": true,
},
Object {
"__v": 0,
"_id": "5cb42d6635ab9132e0e0b994",
"bank_code": "Maybank",
"country": "5cb04a7e23479e39e495f2b6",
"created_date": "2019-04-15T07:06:14.701Z",
"name": "Maybank",
"status": true,
},
Object {
"__v": 0,
"_id": "5cd4e8b0c4022833942eafe0",
"bank_code": "HongLeong",
"country": "5cb04a7e23479e39e495f2b6",
"created_date": "2019-05-10T02:57:52.130Z",
"name": "HongLeong",
"status": true,
},
Object {
"__v": 0,
"_id": "5cd4ee47c4022833942eafe2",
"bank_code": "testbankcode",
"country": "5cbfc9c99b7d064464592948",
"created_date": "2019-05-10T03:21:43.534Z",
"name": "testbank",
"status": true,
},
]
And below is how my RNPickerSelect component looks like and how I'm trying to map the data from "bankResponseArray" :-
<RNPickerSelect
placeholder={{}}
useNativeAndroidPickerStyle={false}
items={this.state.bankResponseArray.map(obj =>
[{
label: obj.name,
value: obj._id,
color: "rgba(77,38,22,1)"
}]
)}
onValueChange={(value, index) => {
this.setState({
bankID: value
});
}}
onClose={() => {
// this._changeGender()
}}
style={{ ...pickerSelectStyles }}
value={this.state.businessType}
ref={el => {
this.inputRefs.picker = el;
}}
hideIcon={Platform.OS === "ios" ? false : true}
doneText={translate("common_done")}
// disabled={!canSubmit}
/>
The expected results were to have the RNPickerSelect display 4 selections which are "RHB, Maybank, HongLeong, testbank". But currently the way I'm trying to map my array to the RNPickerSelect is getting the error of "Type Error. undefined is not an object (evaluating this.state.selectedItem.label".
You should to return an object directly and not an array.
You can use like this:
items={this.state.bankResponseArray.map(obj => (
{
key: obj._id,
label: obj.name,
value: obj._id,
color: "rgba(77,38,22,1)",
}))}

Get Latitude and Longitude from Google Places Autocomplete in React Native

I've implemented autocomplete for my address field, but the json returned from the Google Maps Places Autocomplete doesn't include the geocoded coords for the places.
There are some answers out there that don't seem to fit. For instance, this one refers to things like google.maps.places.Autocomplete(input, options); which I don't think is a thing in React Native.
Other answers appear to be based on react-native-google-places-autocomplete, but I've implemented this myself and I'd love to not do it again using that module.
Here's my method where I call the API.
async handleAddressChange() {
const url = `https://maps.googleapis.com/maps/api/place/autocomplete/json?key=${GoogleAPIKey}&input=${this.state.address}`;
try {
const result = await fetch(url);
const json = await result.json();
this.setState({ addressPredictions: json.predictions });
} catch (err) {
console.error(err);
}
}
setAddress(prediction) {
this.setState({ address: prediction.description, showPredictions: false });
}
The API response doesn't have any place or geometry property on it:
Object {
"description": "1234 Some Avenue Northeast, Washington, DC, USA",
"id": "4c79fba1b3a5ad33478b79b54896a75a4d56ca53",
"matched_substrings": Array [
Object {
"length": 4,
"offset": 0,
},
],
"place_id": "ChIJneQ1fBO5t4kRf8mTw4ieb4Q",
"reference": "ChIJneQ1fBO5t4kRf8mTw4ieb4Q",
"structured_formatting": Object {
"main_text": "1234 Some Avenue Northeast",
"main_text_matched_substrings": Array [
Object {
"length": 4,
"offset": 0,
},
],
"secondary_text": "Washington, DC, USA",
},
"terms": Array [
Object {
"offset": 0,
"value": "1600",
},
Object {
"offset": 5,
"value": "Maryland Avenue Northeast",
},
Object {
"offset": 32,
"value": "Washington",
},
Object {
"offset": 44,
"value": "DC",
},
Object {
"offset": 48,
"value": "USA",
},
],
"types": Array [
"street_address",
"geocode",
],
}
I have found a solution for the same-
Just use like this-
<GooglePlacesAutocomplete
GooglePlacesDetailsQuery={{ fields: "geometry" }}
fetchDetails={true} // you need this to fetch the details object onPress
placeholder="Search"
query={{
key: "API_KEY_GOES_HERE",
language: "en", // language of the results
}}
onPress={(data: any, details: any = null) => {
console.log("data", data);
console.log("details", details);
console.log(JSON.stringify(details?.geometry?.location));
}}
onFail={(error) => console.error(error)} />
Once you have the place id (ChIJneQ1fBO5t4kRf8mTw4ieb4Q for the example in your question), you can do a place details request.
Make sure you include the Places library in your API call: https://maps.googleapis.com/maps/api/js?libraries=places and a valid API key.
function initialize() {
var map = new google.maps.Map(document.getElementById('map-canvas'), {
center: new google.maps.LatLng(0, 0),
zoom: 15
});
var service = new google.maps.places.PlacesService(map);
service.getDetails({
placeId: 'ChIJneQ1fBO5t4kRf8mTw4ieb4Q'
}, function(place, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
// Create marker
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
// Center map on place location
map.setCenter(place.geometry.location);
}
});
}
initialize();
#map-canvas {
height: 160px;
}
<div id="map-canvas"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places&callback=initialize">
</script>