How Can I Parse SOAP Data in React Native - javascript

How Can I Parse SOAP Data in React Native? I need help pls someone help me, i tried, if i write console.log(channels[0]);
is output;
just {
The contents of the view appear blank on the screen.
constructor(props) {
super(props);
this.state = ({
channels: [],
});
}
componentDidMount() {
axios.post('xxxx', xmls, {
headers: {
'Content-Type': 'text/xml',
Accept: 'application/xml',
},
})
.then((response) => {
const channels = convert.xml2json(response.data, {alwaysArray:true,ignoreAttributes: true, compact: true, ignoreDeclaration: true, fullTagEmptyElement: true, spaces: 4 })
this.setState({ channels: [] })
console.log(channels);
})
.catch(err => console.log(err));
}
render() {
return (
<View>
{this.channels.map((v, id) => {
<View key={id}>{v.item}</View>
})}
</View>
)
}
}

Related

How do you re-render Flatlist when value of dropdown list changes?

I am fetching an array from the database in Componentdidmount in the state variable this.state.dataSource
componentDidMount(){
fetch("http://docbook.orgfree.com/home.php", {
method: "GET",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"auth-token": "my token",
},
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson,
});
if (responseJson) {
Alert.alert("Id is" + JSON.stringify(responseJson));
// this.state.dataSource = this.state.dataSource.filter(x => x.Tag === this.state.text);
// console.log(this.state.dataSource[0])
} else if (responseJson.error) {
Alert.alert(responseJson.error);
}
})
.catch((error) => {
console.error(error);
});
}
this.state.Datasource contains an array like:
[
{
description:"kjs",
tag:"beach",
name:"nkslk",
place:"kdlk",
image:"kgmls"
},
{
description:"knsldk",
tag:"club",
name:"nklf",
place:"dlk",
image:"nkxn"
},
]
I have a dropdown list that contains value of different tags in my database like
beach,club,temple,fort,etc
I want to render only those items in my flat list whose tag matches with the tag in my array and when the dropdown value changes I want to re-render my flatlist to the Array elements which has the new tag
My complete source code:
import React, { Component } from "react";
import { Dropdown } from 'react-native-material-dropdown';
import { Button, View, Text, StyleSheet, Image ,Alert,FlatList} from "react-
native";
class explore extends Component {
constructor(props) {
super(props);
this.state = {
tag: '',
isLoading:true,
dataSource:[]
};
}
componentDidMount(){
fetch("http://docbook.orgfree.com/home.php", {
method: "GET",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"auth-token": "my token",
},
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson,
});
if (responseJson) {
// Alert.alert("Id is" + JSON.stringify(responseJson));
console.log(this.state.dataSource)
} else if (responseJson.error) {
// Alert.alert(responseJson.error);
}
})
.catch((error) => {
console.error(error);
});
}
render() {
const { dataSource, tag } = this.state;
const tagFilter = item => {
if (tag) {
return item.tag === tag;
}
return true;
}
let data = [{
value: 'Church',
}, {
value: 'Beach',
}, {
value: 'Temple',
},{
value:'Waterfall'
},
{
value:'Town'
}];
return (
<View>
<Dropdown
label='TAG'
data={data}
onChangeText={tag => this.setState({ tag })}
/>
<FlatList
data={dataSource.filter(tagFilter)}
ItemSeparatorComponent={this.FlatListItemSeparator}
renderItem={({ item }) => (
<View >
<Text >{item.name}</Text>
<Text >#{item.Tag}</Text>
</View>
)}
keyExatractor={({ name }) => name}
/>
</View>
);
}
}
export default explore;
Save the tags to filter by in state and simple filter your data source inline versus in the onChange callback of the dropdown component. The following destructures tag and dataSource from state, and defines a filter function to be used as array::filter callback. If tag is truthy then apply filter if tags match, otherwise return true to allow item to be passed through, i.e. unfiltered.
this.state = {
text: 'Temple',
isLoading: true,
dataSource: [], // <-- provide defined initial state
tag: '', // <-- tag
};
...
render() {
let data = [{
value: 'Church',
}, {
value: 'Beach',
}, {
value: 'Temple',
}];
const { dataSource, tag } = this.state; // <-- destructure
const tagFilter = item => { // <-- filter callback
if (tag) {
return item.tag.toLowerCase() === tag.toLowerCase(); // <-- compare using lowercase!
}
return true;
}
return (
<View>
<Dropdown
label='TAG'
data={data}
onChangeText={tag => this.setState({ tag })} // <-- save tag to state
/>
<FlatList
data={dataSource.filter(tagFilter)} // <-- filter data
ItemSeparatorComponent={this.FlatListItemSeparator}
renderItem={({ item }) => (
<View >
<Text >{item.name}</Text>
<Text >#{item.Tag}</Text>
</View>
)}
/>
</View>
);
}

Refactoring using Async and await in React?

Im (very) new to react having come from a Java background. I am trying to refactor some existing code to use Async and await.
The error is coming right before my render function() (highlighted with *****) and am getting a "/src/App.js: Unexpected token, expected "," error and cant for the life of me figure out what is going on. Ive tried messing around with } ) and ; and cant quite track it down. Any help is appreciated.
import React, { Component } from "react";
import { FixedSizeGrid } from "react-window";
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
specialties: [],
isLoaded: false,
error: null
};
}
async componentDidMount() {
const response = await fetch (url)
.then(response => response.json())
.then(body => {
const specialties = body.data.specialties;
return specialties;
})
.then(specialties => {
return specialties.map(({ _id, name }) => {
return [_id, name];
})
.then(transformed => {
this.setState({
specialties: transformed,
isLoaded: true,
error: null
});
})
.catch(error => {
this.setState({
specialties: [],
isLoaded: true,
error: error
});
});
}
render() {***********************here
if (this.state.error) {
return <span style={{ color: "red" }}>{this.state.error.message}</span>;
}
if (!this.state.isLoaded) {
return "Loading...";
}
const ITEM_HEIGHT = 35;
return (
<FixedSizeGrid
columnWidth={300}
rowHeight={35}
itemData={this.state.specialties}
height={ITEM_HEIGHT * this.state.specialties.length}
width={600}
itemSize={() => ITEM_HEIGHT}
columnCount={2}
rowCount={this.state.specialties.length}
>
{SpecialtyYielder}
</FixedSizeGrid>
);
}
}
const SpecialtyYielder = ({ columnIndex, rowIndex, data, style }) => {
return (
<div
style={{
...style,
backgroundColor:
(rowIndex + columnIndex) % 2 ? "beige" : "antiquewhite",
display: "flex",
alignItems: "center",
justifyContent: "center"
}}
>
{data[rowIndex][columnIndex]}
</div>
);
};
<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>
You're missing a bracket and paren:
async componentDidMount() {
const response = await fetch (url)
.then(response => response.json())
.then(body => {
const specialties = body.data.specialties;
return specialties;
})
.then(specialties => {
return specialties.map(({ _id, name }) => {
return [_id, name];
})
}) // missing closing bracket and paren
.then(transformed => {
this.setState({
specialties: transformed,
isLoaded: true,
error: null
});
})
.catch(error => {
this.setState({
specialties: [],
isLoaded: true,
error: error
});
});
}
Async/Await
Basically everywhere you used then, you can just use await instead, but in a way such that you don't need a bunch of callbacks and the logic is like synchronous code:
async componentDidMount() {
try {
const response = await fetch (url)
const body = await response.json()
const specialties = body.data.specialties;
const transformed = specialties.map(({ _id, name }) => {
return [_id, name]
})
this.setState({
specialties: transformed,
isLoaded: true,
error: null
})
}
catch(error) {
this.setState({
specialties: [],
isLoaded: true,
error: error
})
}
}
Looks like you might need a better text editor ;). It's in your componentDidMount. At the very end you're missing a ), to close off your .then block and then another curly brace to close componentDidMount
async componentDidMount() {
const response = await fetch (url)
.then(response => response.json())
.then(body => {
const specialties = body.data.specialties;
return specialties;
})
.then(specialties => {
return specialties.map(({ _id, name }) => {
return [_id, name];
})
.then(transformed => {
this.setState({
specialties: transformed,
isLoaded: true,
error: null
});
})
.catch(error => {
this.setState({
specialties: [],
isLoaded: true,
error: error
});
});
})
}
This addresses your syntax error. The way you phrased the question made it seem like you thought the "resolution" to it was to use async/await. You obviously can still do a refactor. Are you interested in still exploring async/await?
You are missing }) in componentDidMount method:
import React, { Component } from "react";
import { FixedSizeGrid } from "react-window";
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
specialties: [],
isLoaded: false,
error: null
};
}
async componentDidMount() {
const response = await fetch (url)
.then(response => response.json())
.then(body => {
const specialties = body.data.specialties;
return specialties;
})
.then(specialties => {
return specialties.map(({ _id, name }) => {
return [_id, name];
})
.then(transformed => {
this.setState({
specialties: transformed,
isLoaded: true,
error: null
});
})
.catch(error => {
this.setState({
specialties: [],
isLoaded: true,
error: error
});
});
})}
render() {
const ITEM_HEIGHT = 35;
return (
<FixedSizeGrid
columnWidth={300}
rowHeight={35}
itemData={this.state.specialties}
height={ITEM_HEIGHT * this.state.specialties.length}
width={600}
itemSize={() => ITEM_HEIGHT}
columnCount={2}
rowCount={this.state.specialties.length}
>
{SpecialtyYielder}
</FixedSizeGrid>
);
}
}
const SpecialtyYielder = ({ columnIndex, rowIndex, data, style }) => {
return (
<div
style={{
...style,
backgroundColor:
(rowIndex + columnIndex) % 2 ? "beige" : "antiquewhite",
display: "flex",
alignItems: "center",
justifyContent: "center"
}}
>
{data[rowIndex][columnIndex]}
</div>
);
};

React Native post request causes infinite loop when displaying array

I am navigating to this 'History' tab from a side menu in React Native Navigation. Got a username for which I get all the 'bookings' made, but I can see in the warning tab that there are countless requests being made even after the component has been mounted, so there's an infinite loop probably caused by setState. Where should I call getHistory(), as in to make only one request, unless of course the component is reloaded. Thank you!
constructor(props){
super(props);
this.state = {
loggedUser: 'none',
bookingsInfo: []
}
}
getData = async () => {
try {
const value = await AsyncStorage.getItem('loggedUser')
if(value !== null) {
this.setState({
loggedUser: value
})
}
} catch(e) {
console.error(e);
}
}
getHistory() {
fetch('https://porsche.e-twow.uk/reactnative/istoric.php', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'Cache-Control': 'no-cache, no-store'
},
body: JSON.stringify({
username: this.state.loggedUser
})
})
.then((response) => response.json())
.then((data) => {
this.setState({
bookingsInfo: data
});
})
.catch((error) => {
console.error(error);
});
}
componentDidMount() {
this.getData();
}
render() {
this.getHistory();
return (
<View style={styles.view}>
<ScrollView style={styles.scrollView}>
{
this.getHistory()
}
{
this.state.bookingsInfo ? this.state.bookingsInfo.map((item, index) => {
return (
<View style={styles.mainButton} key={item.id_scooter}>
<Text style={styles.mainButtonText}>Scooter-ul {item.id_scooter}</Text>
<Text style={styles.mainButtonText}>Data start: {item.start}</Text>
<Text style={styles.mainButtonText}>Data final: {item.end}</Text>
</View>
)
}) : null
}
</ScrollView>
<Footer/>
</View>
);
}
}
you are setting state in render.Calling setState here makes your component a contender for producing infinite loops.
place getHistory in componentDidMount .
componentDidMount() {
this.getHistory();
}

How to insert params in the fetch url in React Native?

My skills in React Native is basic, i want to insert the params id in the url to show the posts according to the category.
export default class PostByCategory extends Component {
static navigationOptions = ({ navigation }) => ({
title: `${navigation.state.params.Title}`,
});
constructor(props) {
super(props);
this.state = {
isLoading: true,
};
}
componentDidMount() {
return fetch(ConfigApp.URL+'json/data_posts.php?category='`${navigation.state.params.IdCategory}`)
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson
}, function() {
});
})
.catch((error) => {
console.error(error);
});
}
You have to replace navigation.state.params.IdCategory with this.props.navigation.state.params.IdCategory.
It's not a good practice to manually concat your params to the url. I suggest you look at this question to learn how to properly construct your query string.
componentDidMount() {
return fetch(ConfigApp.URL+'json/data_posts.php?category='+this.props.navigation.state.params.IdCategory)
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson
}, function() {
});
})
.catch((error) => {
console.error(error);
});
}

Loading Json response to a dropdown in react native

I'm using a material dropdown in my application
<Dropdown
baseColor='white'
itemColor='white'
label='Select Cluster'
/>
I fetch JSON object like this and it works fine.
fetch('url', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username : "admin"
})
}).then((response) => response.json())
.then((responseJson) => {
var count = Object.keys(responseJson.message.Obj).length;
for(var i=0;i<count;i++){
console.log(responseJson.message.Obj[i].name) // I need to add
//these names to dropdown
}
})
.catch((error) => {
console.error(error);
});
Now I need to add the responseJson.message.Obj[i].name values to
my dropdown list.
Supposing that you're using react-native-material-dropdown.
Example:
Dropdown component should be rendered as follows:
<Dropdown
baseColor='white'
itemColor='white'
label='Select Cluster'
data={this.state.drop_down_data} // initialise it to []
/>
Request code:
fetch('url', {
...
}).then((response) => response.json())
.then((responseJson) => {
var count = Object.keys(responseJson.message.Obj).length;
let drop_down_data = [];
for(var i=0;i<count;i++){
console.log(responseJson.message.Obj[i].name) // I need to add
drop_down_data.push({ value: responseJson.message.Obj[i].name }); // Create your array of data
}
this.setState({ drop_down_data }); // Set the new state
})
.catch((error) => {
console.error(error);
});
Doc:
React native state management
react-native-material-dropdown
You can achieve this by using react native "state". Create a state then assign it to Dropdown component's data property. Then set responseJson.message.Obj[i].names to the state by using "this.setState()" method.
Find out what is the shape of the data property needed (i.e. Array of Objects) for the <Dropdown /> component you are using
Make fetch calls inside componentDidMount
Treat the state of your component as if it were immutable (do not push directly to this.state. dropdownData)
Here is some sample code using react-native-material-dropdown:
class Example extends React.Component {
// Use constructor to assign initial state
constructor(props) {
this.state = {
dropdownData: []
};
}
componentDidMount() {
fetch('url', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username : "admin"
})
})
.then((response) => response.json())
.then((responseJson) => {
var count = Object.keys(responseJson.message.Obj).length;
// We need to treat this.state as if it were immutable.
// So first create the data array (tempDataArray)
var tempDataArray = [];
for(var i=0;i<count;i++){
// Note: react-native-material-dropdown takes an Array of Objects
tempDataArray.push({
value: responseJson.message.Obj[i].name
});
}
// Now we modify our dropdownData array from state
this.setState({
dropdownData: tempDataArray
});
})
.catch((error) => {
console.error(error);
});
}
// ...
render() {
return (
// ...
<Dropdown
baseColor='white'
itemColor='white'
label='Select Cluster'
data={this.state.dropdownData} // Use dropdownData for the data prop
/>
// ...
);
}
// ...
}
See: AJAX Requests in React
See: react-native-material-dropdown expected data type
Sample code
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, View, Platform, Picker, ActivityIndicator, Button, Alert} from 'react-native';
export default class AddInventory extends Component {
constructor(props)
{
super(props);
this.state = {
isLoading: true,
PickerValueHolder : ''
}
}
componentDidMount() {
return fetch('https://reactnativecode.000webhostapp.com/FruitsList.php')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson
}, function() {
// In this block you can do something with new state.
});
})
.catch((error) => {
console.error(error);
});
}
GetPickerSelectedItemValue=()=>{
Alert.alert(this.state.PickerValueHolder);
}
render() {
if (this.state.isLoading) {
return (
<View style={{flex: 1, paddingTop: 20}}>
<ActivityIndicator />
</View>
);
}
return (
<View style={styles.MainContainer}>
<Picker
selectedValue={this.state.PickerValueHolder}
onValueChange={(itemValue, itemIndex) => this.setState({PickerValueHolder: itemValue})} >
{ this.state.dataSource.map((item, key)=>(
<Picker.Item label={item.fruit_name} value={item.fruit_name} key={key} />)
)}
</Picker>
<Button title="Click Here To Get Picker Selected Item Value" onPress={ this.GetPickerSelectedItemValue } />
</View>
);
}
}
const styles = StyleSheet.create({
MainContainer :{
justifyContent: 'center',
flex:1,
margin: 10
}
});
You could also take an approach like this:
var Somedata = {
"data" : [
{
"baseColor": "white",
"moreData":[
{
"id" : 118,
}
]
},
{
"baseColor": "grey",
"moreData": [
{
"id": 1231231,
}
]
}
]
}
const renderData = someData.data.map((data) => {
return data.moreData.map(brand => {
strColor = data.baseColor;
console.log("Individual Data :" + strColor)
return `${data.baseColor}, ${moreData.id}`
//setState here?
}).join("\n")
}).join("\n")
//setState here?
You now have a few options you could set the state. From your example, you would set the state the state of your list to the data returned from the fetch call once it has been rendered. A quick thing to keep in mind is that react doesn't support asynchronous loading currently. Therefore the data must be rendered as empty, or with some sample data and then updated once the call has been made to whatever you wish to update! Hope this helps a little :)
https://reactjs.org/docs/faq-ajax.html

Categories