how to use array from axios post in react native - react-native

I'm fairly new to React Native. I have successfully fetched the required array through axios.post, in the following format:
"hospitals": [
{
"title": "Holy Family Hospital Rawalpindi",
"distance": "71.45372179866516"
},
{
"title": "Fauji Foundation Hospital Islamabad",
"distance": "62.242918533343705"
},
{
"title": "PIMS Hospital Islamabad",
"distance": "80.0576175928936"
}
I'm trying to display only the titles in a dropdown list and continuously failing. I just dont know the correct format/protocol for this (ie how to use individual values). Any help would be appreciated.

https://reactnative.dev/docs/picker
I think u wanna use that.
just map the items. like that:
<Picker
selectedValue={selectedValue}
style={{ height: 50, width: 150 }}
onValueChange={(itemValue, itemIndex) => setSelectedValue(itemValue)}
>
data.map((data)=>{
return( <Picker.Item label=data.title value=data.title />)
})
</Picker>

Related

React Native Mapbox custom cluster pie chart

I'm using the package react-native-mapbox-gl/maps to generate a map with clustering. I need to be able to analyze each cluster and based on its contents generate a pie chart representing the different types of points within the cluster. Either it isn't possible or I can't figure it out given the different types of Layers and Sources. I'm honestly not even sure where to begin. Any help or pointing in the right direction is much appreciated!
I've been able to create my map using the react-native-maps package (Google Maps) and have custom clusters, but I find the memory usage of the Mapbox package to be so much better.
There is nothing special about how I'm generating my map but here is the code:
const mapStyles = {
icon: {
iconImage: ['get', 'icon'],
iconSize: [
'match',
['get', 'icon'],
'park', 0.9,
'parkLarge', 1.6,
'school', 0.9,
'schoolLarge', 1.6,
1, /* default */
],
iconAllowOverlap: true
},
clusteredPoints: {
circlePitchAlignment: 'map',
circleColor: [
'step',
['get', 'point_count'],
'#2A2E43',
100,
'#2A2E43',
750,
'#2A2E43',
],
circleRadius: ['step', ['get', 'point_count'], 20, 100, 30, 750, 40],
circleOpacity: 1,
circleStrokeWidth: 4,
circleStrokeColor: 'white',
},
clusterCount: {
textColor: 'white',
textField: '{point_count}',
textSize: 12,
textPitchAlignment: 'map',
},
};
<MapboxGL.MapView
ref={ref => (this.map = ref)}
style={{ flex: 1, zIndex: 100 }}
styleURL="mapbox://[hidden]"
onPress={() => this.props.onPressMap()}
onRegionDidChange={(region) => this.onRegionDidChange(region)}
onRegionWillChange={() => this.props.onRegionWillChange()}
pitchEnabled={false}
rotateEnabled={false}
localizeLabels={true}
>
<MapboxGL.UserLocation visible={true} />
<MapboxGL.Camera
ref={(c) => this.camera = c}
zoomLevel={this.props.zoomLevel}
centerCoordinate={this.props.location}
animationMode={'flyTo'}
animationDuration={200}
style={{ paddingBottom: 300 }}
/>
<MapboxGL.Images images={{ park: parkIcon, parkLarge: parkIcon, school: schoolIcon, schoolLarge: schoolIcon }} />
{
this.props.featureCollection && this.props.featureCollection.features && this.props.featureCollection.features.length > 0 ? (
<View>
<MapboxGL.ShapeSource
id="pointsSource"
shape={this.props.featureCollection}
onPress={(event) => this.props.onPressMarker(event)}
cluster
clusterRadius={80}
clusterMaxZoomLevel={14}
>
<MapboxGL.SymbolLayer
id="pointCount"
style={mapStyles.clusterCount}
/>
<MapboxGL.CircleLayer
id="clusteredPoints"
belowLayerID="pointCount"
filter={['has', 'point_count']}
// filter={['>', 'point_count', 1]}
style={mapStyles.clusteredPoints}
/>
<MapboxGL.SymbolLayer
id="favoritesIcons"
filter={['!', ['has', 'point_count']]}
// filter={['==', 'point_count', 1]}
style={mapStyles.icon}
/>
</MapboxGL.ShapeSource>
</View>
) : null
}
</MapboxGL.MapView>
Though the relevant example in our documentation is built with Mapbox GL JS rather than React Native, you might find this display HTML clusters with custom properties example to be a good starting point. It demonstrates how to make use of expressions to create pie chart-like SVGs for each cluster, depending on the properties of the data in the particular cluster.
A similar approach (manually synchronizing the clustered source with a pool of marker objects that updates continuously while the map view changes, rather than using a Mapbox GL layer to display the clusters) will likely be necessary in a React Native implementation as well.

React-Native-Material-Dropdown not showing data on Front-end

I have used react-native material dropdown to fetch data from my API as follows:
<Dropdown
label='colors'
data={this.state.data.colors}
containerStyle={{width: 50}}
/>
{console.log("sbHASB",this.state.data.colors)}
However when I implement thi, I do get the colors on my log but they do not seem to appear on the list, it seems to be blank, can anyone please tell me why is ot so?
Any help would be great, thank you.
my logs after implementing are as follows:
sbHASB ["Blue", "White", "Blue", "White", "Blue", "White", "Blue", "White"]
Do tell me if you require anything else.
Assuming you are using react-native-material-dropdown, the documentation on their github suggests that the data prop should be a list of objects with a value key. See here the example given.
import React, { Component } from 'react';
import { Dropdown } from 'react-native-material-dropdown';
class Example extends Component {
render() {
let data = [{
value: 'Banana',
}, {
value: 'Mango',
}, {
value: 'Pear',
}];
return (
<Dropdown
label='Favorite Fruit'
data={data}
/>
);
}
}
For your list to work you should transform it to match this format, for example
const data = this.state.data.colors.map((color) => ({value: color}))
Given your example above that could look like
<Dropdown
label='colors'
data={this.state.data.colors.map((color) => ({value: color}))}
containerStyle={{width: 50}}
/>
However I would advise transforming the data before this step, for example when you receive the response from the api.
see this example on snack.io, the dropdown will work best if you preview it on a device since the animation doesn't display properly on the web preview.
https://snack.expo.io/#dannyhw/dropdown
UPDATE:
Here is the updated example that includes an example of how it can be used dynamically
export default class App extends React.Component {
state = {
data: {colors: []}
}
getSomeData() {
// imagine this is your api call here and it returns a promise that resolves to be a list of colours
return Promise.resolve(["green", "White", "Blue", "White", "Blue", "White", "Blue", "White"])
}
componentDidMount(){
this.getSomeData().then((result)=> {
this.setState(state => state.data.colors = result)
})
}
render() {
return (
<View style={styles.container}>
<Dropdown
label='colors'
data={this.state.data.colors.map((color) => ({value: color}))}
containerStyle={{width: 150}}
/>
</View>
);
}
}

How to show/hide raster layer (visibility property visible/none) at run time in react-native-mapbox-gl

I have set custom style url in map initialization. Like :
<Mapbox.MapView
styleURL="asset://mystyle.json"
logoEnabled={false}
attributionEnabled={false}
ref={(e) => { this.oMap = e }}
animate={true}
zoomLevel={6}
centerCoordinate={[54.0, 24.0]}
style={{ flex: 1 }}
showUserLocation={true}>
</Mapbox.MapView>
In mystyle.json I have two base map as below :
{
"id": "Satellite",
"type": "raster",
"source": "Satellite",
"layout": {
"visibility": "visible"
},
"paint": {
"raster-opacity": 1
}
},
{
"id": "Satellite2",
"type": "raster",
"source": "Satellite",
"layout": {
"visibility": "none"
},
"paint": {
"raster-opacity": 1
}
}
Satellite is visible default.
How to set visibility of satellite property to none and satellite2 visibility to visible at run time?
Mapbox gl :
"#mapbox/react-native-mapbox-gl": "^6.1.3"
React native :
"react-native": "0.58.9",
Finally I got solution :
constructor() {
this.state = {
lightMap: 'visible',
darkMap: 'none'
};
}
changeMap(){
this.setState({darkMap:'visible'})
}
<MapboxGL.MapView
styleURL="asset://mystyle.json"
logoEnabled={false}
attributionEnabled={false}
ref={(e) => { this.oMap = e }}
zoomLevel={6}
centerCoordinate={[54.0, 24.0]}
style={{ flex: 1 }}>
<MapboxGL.RasterSource
id="idLightMap"
url="LAYERURL1"
tileSize={256}>
<MapboxGL.RasterLayer
id="idLightMap"
sourceID="idLightMap"
style={{visibility: this.state.lightMap}}>
</MapboxGL.RasterLayer>
</MapboxGL.RasterSource>
<MapboxGL.RasterSource
id="idDarkMap"
url="LAYERURL2"
tileSize={256}>
<MapboxGL.RasterLayer
id="idDarkMap"
sourceID="idDarkMap"
style={{visibility: this.state.darkMap}}>
</MapboxGL.RasterLayer>
</MapboxGL.RasterSource>
</MapboxGL.MapView>
I have added raster layer and programmatic toggling it.
let say we have one state isStateliteVisible:false,
now change this state to true when you want to visibility
and use mapbox like this,
<Mapbox.MapView
styleURL={this.state.isStateliteVisible?...visiblityStyle:....noneStyle} // use this as per your case
logoEnabled={false}
attributionEnabled={false}
ref={(e) => { this.oMap = e }}
animate={true}
zoomLevel={6}
centerCoordinate={[54.0, 24.0]}
style={{ flex: 1 }}
showUserLocation={true}>
</Mapbox.MapView>
I can see that you are using a older depreciated version of mapbox-gl.
This package is deprecated please use this instead.
Installation
Dependencies
node
npm
React Native recommended version 0.50 or greater
Git
git clone git#github.com:mapbox/react-native-mapbox-gl.git
cd react-native-mapbox-gl
Yarn
yarn add #mapbox/react-native-mapbox-gl
Npm
npm install #mapbox/react-native-mapbox-gl --save
You're good to go!

How to Delete html tags form responseJson in react native?

How can I delete html tags? I need to show description, but html tag not support in react native.
json:
[
{
"id": 73,
"name": "Hello World",
"status": "publish",
"description": "<p>hello</p>\n",
...
codes:
componentDidMount(){
return fetch('example.com/testttttttttttttttttttttttttttttttttt')
.then((response)=>response.json()).
then((responseJson)=>{
let ds = new ListView.DataSource({rowHasChanged:(r1,r2)=>r1!=r2});
this.setState({
isLoading:false,
dataSource:ds.cloneWithRows(responseJson)
});
}).catch((error)=>console.error(error));
}
and listView:
<ListView
dataSource={this.state.dataSource}
renderRow={ (rowData)=>
<View style={{width:'100%',height:40}}>
<View style={{marginTop:5,marginBottom:5}}>
<Text>{rowData.name}</Text>
<Text>{rowData.description}</Text>
</View>
</View>
}
/>
Stripping html tags is not a trivial problem. Many issues have been discussed in the question Strip HTML from Text JavaScript.
In my opinion, the best approach would be to use a library like striptags. Then your code would look like:
<Text>{striptags(rowData.description)}</Text>
Another, more naive implementation could use String.prototype.replace:
<Text>{rowData.description.replace(/<(?:.|\n)*?>/gm, '')}</Text>

Cells/Rows in the <SectionList/> loading slowly on Android

I use the new API <SectionList/> to build a list UI, but I found issues running on Android devices.
While scrolling down with SectionList, only a few new cells/rows can be displayed at once. You need to scroll SectionList down again to display the next a few new cells/rows, and wait for the next cells are ready to be displayed. It works not the same on the iOS.
When reaching the last item in the SectionList, I tried to scroll up quickly to the first item in the SectionList, and it display a blank view with a few seconds till the cells are rendered.
I have hundred rows (country list) for display, and the user experience is bad. The user takes many seconds to reach the last item in the country list, and takes many seconds to show the previous rows after scrolling up quickly.
export default class LoginCountryList extends React.Component {
props: LoginCountryListProps;
static defaultProps = {
data: {},
};
renderRow = (rowItem: any) => {
console.log('render row:');
return (
<TouchableHighlight
onPress={() => this.props.onSelectRow(rowItem.item)}
>
<View style={styles.row}>
<Text style={styles.rowLeftText}>{rowItem.item.name}</Text>
<Text style={styles.rowRightText}>{`+${rowItem.item.ccc}`}</Text>
</View>
</TouchableHighlight>
)
};
renderSectionHeader = (sectionItem: any) => (
<View
style={styles.sectionHeader}
>
<Text style={styles.sectionHeaderText}>{sectionItem.section.title}</Text>
</View>
);
render() {
console.log('re-render section list')
return (
<View style={styles.container}>
<NavigationBar.TextStyle
title={title}
leftText={leftText}
onLeft={this.props.onBack}
/>
<SectionList
style={styles.listView}
sections={this.props.data}
renderItem={this.renderRow}
renderSectionHeader={this.renderSectionHeader}
/>
</View>
);
}
}
// data:
const data = [
// first section
{
"title": "A",
"key": "A",
"data": [
// first row
{
"ccc": "93",
"countryCode": "AF",
"currencyCode": "AFN",
"currencySymbol": "؋",
"name": "Afghanistan",
"key": "AF"
},
{
"ccc": "355",
"countryCode": "AL",
"currencyCode": "ALL",
"currencySymbol": "Lek",
"name": "Albania",
"key": "AL"
},
...
]
},
...
]
I tried to log in the renderItem callback when SectionList did display, and it calls renderItem hundred times for displaying only 15 rows in the first section.
Log a constant string render row: with hundred times when the SectionList did display:
Log the indexes of the items when the SectionList did display. The same row did render multiple times when the SectionList did display.
Did use SectionList wrongly? How do I do to fix it?
Environment
react-native -v: 0.45.1 & 0.46.1 (tried both version)
node -v: v7.8.0
npm -v: 4.2.0
yarn --version (if you use Yarn): 0.22.0
Target Platform (e.g. iOS, Android): Android
Development Operating System (e.g. macOS Sierra, Windows 10): macOS
Build tools (Xcode or Android Studio version, iOS or Android SDK version, if relevant): Android SDK 25.0.2