React Native - Update and Delete by ID - javascript

I'am trying to Update and Delete some items by ID upon tap/click of Update And Remove buttons. But my problems is, I'm not sure what is the proper approach doing a "fetch with a state(or anything) for the ID's".
With these approach, I have errors. (Ex: undefined is not an object ...)
Without these, I have nothing. I'am well aware of that because I'm not referring to anything. So I have to use ID. But I don't know the approach.
Please help, anything will be appreciated. :)
Here is my code
Settlement.js
export default class Settlement extends Component {
constructor(props){
super(props)
this.state = {
...
deleteOrder: '',
numOrder: '',
};
}
submit = () => {
this.state.numOrder = item.order_id; // here's my fetch with state
fetch('http://192.168.254.***:****/SendOrder/update' + this.state.numOrder, {
method: 'PUT',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
spcl_req: this.state.SplOrder,
order_quantity: this.state.count,
order_type: this.state.DineIn,
})
}).then(res => res.json())
.then((responseJson) => {
Alert.alert(JSON.stringify(responseJson))
console.log(responseJson);
})
.catch(error => console.error('Error:', error))
}
delete = () => {
this.state.deleteOrder = item.order_id; // here's my fetch with state
fetch('http://192.168.254.***:****/SendOrder/delete_order/' + this.state.deleteOrder, {
method: 'DELETE',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
order_id: this.state.deleteOrder
})
}).then((responseData) => {
Alert.alert(JSON.stringify(responseData))
console.log(responseData.rows)
}).done();
}
render() {
const { params } = this.props.navigation.state;
return (
<View>
<FlatList
...
renderItem = {({ item }) =>
<View>
....
<View>
<TouchableOpacity
onPress = { () => this.submit() }>
<Text>UPDATE</Text>
</TouchableOpacity>
<TouchableOpacity
onPress = { () => this.delete() }>
<Text>REMOVE</Text>
</TouchableOpacity>
</View>
</View>
}/>
</View>
)
}
}[![enter image description here][1]][1]

You broke a couple of concepts in React.
this.state.numOrder = item.order_id;
This line will not update your state
What's in the item in this line? renderItem = {({ item }) =>
Perhaps in this object there is an identifier, which must be passed as an argument to your functions

Related

React Native Fetch API json returning old data

I am new to react native and I have a problem receiving an image with a link from a json api.
I have an app and in a section of the screen I am putting an image that can vary depending on the name of the image that I put in the json. It is something quite simple, but for the moment it is what I need for the app.
The problem is the following: when I change the url from where the application will take the image and the link that that image will redirect to the user, the app continues presenting the old link and the old image.
I have changed several times and also read that putting "'Cache-Control: no-cache'" this would solve, but it has not been my case.
I would greatly appreciate your help please and thank you in advance.
Here is my code:
JSON
{
"Home": [
{
"id": "1",
"LinkHome":"https://www.instagram.com/masterchefrdominicana/?hl=es",
"URLHome":"https://teleantillas.com.do/wp-content/uploads/telestream/banners/mchef.jpeg"
}
]}
MY CODE:
export default class GetDatajson extends Component{
constructor(props) {
super(props);
this.state = {
data: [],
isLoading: true
};
}
async fetchData(){
try{
const response = await
fetch
('https://teleantillas.com.do/wp-content/uploads/telestream/json/PublicidadTeleStream.json',
{
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
}
})
const json = await response.json();
this.setState({ data: json.Home });
}catch(error) { console.error(error);}
finally{
this.setState({ isLoading: false });
}
}
componentDidMount() {
this.fetchData();
}
render(){
const { data, isLoading } = this.state;
return(
<View style ={styles.jsonHome}>
{isLoading ? <ActivityIndicator/> : (
<FlatList
data={data}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => (
<TouchableOpacity style={styles.i8mgcontainer} onPress={()=>
Linking.openURL(item.LinkHome)
}>
<Image
style={styles.imgad}
source={{uri: item.URLHome}}
/>
</TouchableOpacity>
)}
/>
)}
</View>
)
}
}
FlatList uses ID as cache key so if you change your ID when you want receive new data and url, it would be resolved.
https://reactnative.dev/docs/flatlist#keyextractor

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 close popup after submitting values in react native?

I'm using react-native-popup-dialog. There is a single button within popup (yes). I want to close the button at same time I want to submit values to server.Now after clicking on yes button values get submit to server. How do I write close function at same onPress method? following is my code
onPressYes = (workType) => {
AsyncStorage.getItem('userid').then((usid) =>{
this.setState({
'userid': usid
});
console.log(usid);
fetch(GLOBAL.USER_REQUEST,{
method:'POST',
headers:{
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
workType,
usid
})
})
.then(response => response.json())
.then((responseData) => {
this.setState({
data:responseData
});
});
})
}
popUpDialog = (id, workType) => {
this.setState ({
workType: workType
});
this.popupDialog.show();
}
render(){
return(
<PopupDialog ref={popupDialog => {
this.popupDialog = popupDialog;
}}
dialogStyle={{ backgroundColor: "#FFFFFF", height: 180, width:300, borderWidth:1,padding:10}}
overlayBackgroundColor="#fff" onDismissed={() => {
}}>
<View style={styles.dialogContentView}>
<Text style={{fontSize:18, margingTop:10,color:"#000000"}}>Are you sure you want to submit?</Text>
<View style={{alignSelf:'center'}}>
<View style={styles.button_1}>
<Button title="Yes" color="#8470ff" onPress={() => this.onPressYes(workType)}/>
</View>
);
According to your code, you can use this.popupDialog.dismiss() instance method to hide a dialog:
onPressYes = (workType) => {
this.popupDialog.dismiss(); // action to close a dialog
AsyncStorage.getItem('userid').then((usid) =>{
this.setState({
'userid': usid
});
console.log(usid);
fetch(GLOBAL.USER_REQUEST,{
method:'POST',
headers:{
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
workType,
usid
})
})
.then(response => response.json())
.then((responseData) => {
this.setState({
data:responseData
});
});
})
}
Using visible props to control it.
import Dialog, { DialogContent } from 'react-native-popup-dialog';
import { Button } from 'react-native'
<View style={styles.container}>
<Button
title="Show Dialog"
onPress={() => {
this.setState({ visible: true }); // here
}}
/>
<Dialog
visible={this.state.visible} // here
onTouchOutside={() => {
this.setState({ visible: false });
}}
>
<DialogContent>
{...}
</DialogContent>
</Dialog>
</View>
Ref: https://github.com/jacklam718/react-native-popup-dialog

Sending multiple duplicate PUT requests

part of this app I'm working on for class is supposed to be scanning the barcode of a book (using the expo XDE barcodescanner component) and then sending the scanned barcode to a database that another group in my class is handling. My issue right now is that every time I do a scan, I see in my console that I'm sending multiple duplicate PUT requests. I think the problem is that the expo barcodescanner doesn't just scan once and then stop, but keeps on scanning, and each time it scans, my state is "updated" and component is re-rendered. Does anyone have any suggestions on how I can modify my code to make sure that I'm not re-rendering over and over again with the same data? I've included the relevant code below. Note: some of the data is hard-coded for testing purposes. Thank you!
class SecondScreen extends Component {
constructor(props) {
super(props);
this.state= {
results: []
}
this.fetchData = this.fetchData.bind(this);
}
fetchData(URL) {
return fetch(URL)
.then((response) => response.json())
.then((responseData) => {
return responseData
})
.catch((error) => {
console.error(error)
})
}
_handleBarCodeRead = data => {
let isbn = data.data;
let URL = 'https://www.googleapis.com/books/v1/volumes?q=isbn:' +
isbn;
this.fetchData(URL).then(bookResult => {
this.setState({ results: bookResult }
fetch('https://p0kvnd5htd.execute-api.us-east-
2.amazonaws.com/test/return', {
method: 'PUT',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
'libraryName': 'lib1', //libName
'bookBarcode': '18263' //isbn
}),
})
.then((response) => {
if (response.status == 400) {
console.log(response.status)
alert('Return unsuccessful, please try again.');
}
else {
console.log(response.status)
this.props.navigation.navigate('ThirdPage', { title:
this.state.results.items[0].volumeInfo.title });
}
})
})
}
render() {
return (
<BarCodeScanner
onBarCodeRead={this._handleBarCodeRead}
style={[StyleSheet.absoluteFill, styles.container]}
>
<View style={styles.layerTop} />
<View style={styles.layerCenter}>
<View style={styles.layerLeft} />
<View style={styles.focused} />
<View style={styles.layerRight} />
</View>
<View style={styles.layerBottom} />
</BarCodeScanner>
);
}
}
Easy fix would be to use lodash's debounce function:
command line: npm i lodash
top of javascript:
import _ from 'lodash'
wrap _handleBarCodeRead in debounce, this will prevent _handleBarCodeRead from being called multiple times for 3 seconds after the last call:
_debouncedHandleBarCodeRead = _.debounce((data) =>{ this._handleBarCodeRead(data) }, 3000, {leading: true, trailing: false});
change BarCodeScanner to used the debounced method:
<BarCodeScanner onBarCodeRead={this._debouncedHandleBarCodeRead} >

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