How to fill picker in react native from array - arrays

i want to fill a picker items from array .. this array store data from local storage and i want to display this data on picker
this is my function that retrieve data from local storage
async getElementsInLocalStorage() {
try{
let x = [];
let all_keys = await AsyncStorage.getAllKeys();
for(i = 1; i <= all_keys.length;i++ ){
let converter = JSON.parse(await AsyncStorage.getItem('one_person'+i));
x[i] = converter.first_name + ' ' + converter.last_name;
}
this.setState({all_options: x, data: x,});
} catch(error){
alert(error)
}
}
And this is my constructor
constructor(){
super();
this.state = {
first_name: '',
last_name : '',
all_options : [],
};
data = [];
}
And this is my Picker
<Picker selectedValue = {this.state.selected} >
{this.state.data.map((value)=><Picker.Item label={value} value={value}/>)}
</Picker>
when type data only in picker picker not filled but when type this.state.data
this is error return

You have defined data as a seperate variable in constructor. But after fetching data you are considering data as a state variable.
Just declare data inside state, and that might solve your issue.
constructor(){
super();
this.state = {
first_name: '',
last_name : '',
all_options : [],
data:[]
};
}

Can you try this. What I did is
Moved data inside state and added conditional check before doing .map
constructor(){
super();
this.state = {
first_name: '',
last_name : '',
all_options : [],
data = []
};
}
And this is my Picker
<Picker selectedValue = {this.state.selected} >
{this.state.data && this.state.data.map(value=> (<Picker.Item label={value} value={value}/>))}
</Picker>

Related

Covert object to array in react for plotly

How do you convert an object to an array in js ? (or is there a better way to dynamically update a nested object)
Basically I'm trying to update some data for the plotly component from an axios request on the fly, but plotly complains it is fed an object instead of an array.
Part of the code :
var trace0 = {
type: 'ohlc',
xaxis: 'x',
yaxis: 'y',
increasing: {line: {color: 'green'}},
decreasing: {line: {color: 'red'}},
line: {color: 'rgba(31,119,180,1)'},
x: ['2017-01-17'],
open: [118.339996],
high: [120.239998],
low: [118.220001],
close: [120],
};
var init_data = [trace0];
export default class GraphRAW extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
layout: {},
config: {},
checking:false,
revision: 0
};
}
getStart = () => {
const symbol = 'tst'
return axios
.post(API_URL + "startRAW", {symbol } )
.then((response) => {
if (response.data) {
var newData = Object.assign({}, this.state.data);
newData[0].x = response.data.x;
newData[0].close = response.data.close;
newData[0].open = response.data.open;
newData[0].low = response.data.low;
newData[0].high = response.data.high;
console.log('new data here =>');
console.log(newData); // Data seems ok in console
console.log(typeof(newData)); // Typeof new data is object
this.setState({data: newData });
this.setState({revision: this.state.revision++}); // Update revision to initiate a new plot in the plotly component
console.log('this data here =>');
console.log(this.data); // Undefined in console
console.log(typeof(this.data)); // Undefined in console
return response;
}
});
componentDidMount(){
this.setState({config: init_config});
this.setState({layout: init_layout});
this.setState({data: init_data});
this.getStart();
}
Warning: Failed prop type: Invalid prop data of type object supplied to PlotlyComponent, expected an array.
It seems response.data.x (~.close ~.open ~.low ~.high) are objects which need to be converted to an array in the data object.
In the render :
<Plot useResizeHandler data={this.state.data} layout={this.state.layout} config={this.state.config} revision={this.state.revision} style={{width: "100%" }} />
Any help highly appreciated
Posting my comment as an answer:
You just need to wrap the values returned from the server in an array, e.g:
newData[0].x = [response.data.x];

React - state like list is losing value

My problem is this ... I am using a form, however, when I change from one field to another, the value referring to the state of the previous field is lost. With that, at the end of the filling, only the last field of the state is filled.
I solved the problem by including a local variable in onSubmit with the fields filled in, but from what I understand so far, the best practice would be to use state.
Could someone help me and tell me what I am failing to do? Thank you very much.
class AddItem extends React.Component {
constructor(props){
super(props);
this.state = {validated: false};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.state = {
item: {
titulo: '',
descricao: '',
estado: '',
cidade: null,
usuario: 1,
data: new Date(),
}
}
}
handleSubmit (event) {
const form = event.currentTarget;
console.log(item);
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}else{
api(this.state.item);
event.preventDefault();
}
this.setState({validated: true});
};
handleChange (event) {
let name = event.target.name;
let value = event.target.value;
this.setState({item: {[name]: value}});
};
You're not keeping any of the previous values in state: eg this.setState({validated: true}); will mean that the state no longer has an item property.
Spread the previous state into the new state so that old properties don't get lost whenever you call setState:
this.setState({validated: true});
to
this.setState({ ...this.state, validated: true });
and
this.setState({item: {[name]: value}});
to
this.setState({ ...this.state, item: { ...this.state.item, [name]: value }} );

Sending object to firebase using dynamic key value

I have a table component that I am using to display the information from all other components in my app. This means that when I send data I can't use the following:
db.collection(collectionName).add({
key1: val1,
key2: val2,
etc...
})
Because the keys could be different depending on which component is using table. I've thought about doing this with a .map() or forEach going through each key but I keep getting syntax errors.
I originally assumed that I could just send the object new_row but that doesn't seem to work properly.
Here is my table component:
class Table extends Component {
constructor(props){
super(props);
this.state = {
rows: null,
temprows: null,
newrow: null,
parent: this.props.tableComponent
}
}
addRow = function(){
var new_rows = [...this.state.rows];
new_rows.push(this.state.newrow);
var new_row = JSON.parse(JSON.stringify(new_rows[0]));
Object.keys(new_row).forEach(function(index) {
new_row[index] = '';
});
db.collection(collectionNAame).add({
I want to add the data here
})
this.setState({
rows: new_rows,
newrow: new_row
});
}
Is there also a better approach, some other method aside from .add for this specific case?
In db.collection .add method, spread and pass this.state.newrow and in the then block update your state. Also in your addRow function, the new_row should be obtained from state (not new_rows[0]
Like this
class Table extends Component {
constructor(props) {
super(props);
this.state = {
rows: null,
temprows: null,
newrow: {},
parent: this.props.tableComponent
};
}
addRow = function() {
var new_rows = [...this.state.rows];
new_rows.push(this.state.newrow);
// var new_row = JSON.parse(JSON.stringify(new_rows[0]));
var new_row = { ...this.state.newrow };
db.collection(collectionNAame)
.add({
...this.state.new_row
})
.then(() => {
Object.keys(new_row).forEach(function(index) {
new_row[index] = "";
});
this.setState({
rows: new_rows,
newrow: new_row
});
});
};
}

react can not show console log variable

why my log not showing anything ? is ths because the variable isLoading state ?
my code :
function getColumns(data) {
const columns = [];
const sample = data[0];
console.log("theSample" + sample);
and i call it from here :
class App extends React.Component {
constructor() {
super();
this.state = { isLoading: true };
if (this.state.isLoading === false) {
//const data = getData();
const data = this.state.dataExt;
// console.log(data);
const columns = getColumns(data);
this.state = {
data,
columns,
visible: false
};
}
}
Because, you only call getColumns when this.state.isLoading === false, and the initial value of your isLoading state is true. Therefore, unless you update your isLoading state, getColumns wouldn't be called and your log wouldn't show up.

How to insert value from state into a function?

I have an array that is generated from a firebase database query.
I want to save that in state so that as the data changes, it will re-render the screen.
I can't seem to get the value from state into my function. If I put the value from the array, it works, but then it won't automatically re-render when data changes.
Screen shot of it using the array... note the console log is printing that the state is set correctly.
and here it is with the error
It's gotta be right around line 101, but I cannot figure out the right syntax to make thsi work.
UPDATE: I was not initializing state, that was one part of the error.
import React, { Component } from 'react';
import Flexbox from 'flexbox-react';
import firebaseApp from '../api/firebase';
import GeoFire from 'geofire';
var geoRef = firebaseApp.database().ref('shiftgeo');
var geoFire = new GeoFire(geoRef);
var ref = geoFire.ref(); // ref === firebaseRef
var shiftKeys = []; // this array will hold the keys from the geoFire results
var shifts = []; // this array will hold the actual shift data of shifts in the geo, then we will filter it later
console.log(firebaseApp);
export class App extends React.Component {
constructor() {
super();
this.state = {
fname: 'Chris',
lname: 'Chong',
cellphone: '503 830 4313',
email: 'chris#ehotleads.com',
dataSource: ''
};
}
componentWillMount() {
let email = 'chris#ehotleads.com';
let password = '123456789';
firebaseApp.auth().signInWithEmailAndPassword(email, password)
.then((data) => {
//this.setState({ error: 'Account already exists. Logging you in...', loading: false });
console.log('success data', data);
this.setState({
user: data,
});
})
.catch((data) => {
//this.setState({ error: 'Authentication failed.', loading: false });
console.log('error data', data);
});
}
componentDidMount() {
var geoQuery = geoFire.query({
center: [45.616422, -122.580453],
radius: 1000,
});
geoQuery.on("key_entered", function(key, location, distance) {
// dont forget that as shifts are added that match the geo, this will automatically add to the shiftKeys array
//shiftKeys = [];
shiftKeys.push(key)
console.log("Found shift " + key + " at " + location + " (" + distance + " km away)");
});
geoQuery.on("ready", () => {
shifts = []; // we need to blow out the array every time this function runs or it will throw errors
shiftKeys.forEach((shiftKey) => {
//console.log(shiftKey);
let shiftsRef = firebaseApp.database().ref('shifts').child(shiftKey);
shiftsRef.on("value", (snapshot) => {
//console.log(snapshot.val())
//if (snapshot.val().state == "WA" && (snapshot.val().licenseRequired == "CNA" || snapshot.val().licenseRequired == "RN")) {
//if (snapshot.val().licenseType == this.state.licenseType || snapshot.val().licenseRequired == "TEST") {
shifts.push({
key: snapshot.key,
fname: snapshot.val().fname,
lname: snapshot.val().lname,
company: snapshot.val().company,
address1: snapshot.val().address1,
address2: snapshot.val().address2,
city: snapshot.val().city,
state: snapshot.val().state,
zip: snapshot.val().zip,
shiftDate: snapshot.val().shiftDate,
shiftStart: snapshot.val().shiftStart,
shiftLength: snapshot.val().shiftLength,
shiftDescription: snapshot.val().shiftDescription,
licenseType: snapshot.val().licenseType,
logo: snapshot.val().logo,
building: snapshot.val().building,
}) // end shifts.push
var date_sort_asc = function (date1, date2) {
if (date1.shiftDate > date2.shiftDate) return 1;
if (date1.shiftDate < date2.shiftDate) return -1;
return 0;
};
//}
//console.log(this.state.distancePref)
this.setState({
dataSource: shifts,
resultCount: shifts.length,
})
}); // end shiftsRef.on
}); // end shiftKeys map
}); // end geoQuery.on
console.log('ShiftArray: ', shifts)
console.log('StateArray: ', this.state.dataSource)
}
render() {
const listItems = this.state.dataSource.map((shift) =>
<li key={shift.key}>
{shift.address1}
</li>
);
console.log('ShiftArray: ', shifts)
console.log('StateArray: ', this.state.dataSource)
return (
<Flexbox flexDirection="column" minHeight="100vh">
<Flexbox element="header" height="60px">
Header link one
</Flexbox>
<Flexbox flexGrow={1}>
<Flexbox
width="20%"
minWidth="200px"
maxWidth="300px"
style={{ backgroundColor: '#ba0000' }}>
Sidebar Menu Goes Here
</Flexbox>
<Flexbox width="80%" flexDirection="row" style={{ backgroundColor: '#FFF' }}>
<div>List of Shifts Addresses</div>
<ul>{listItems}</ul>
</Flexbox>
</Flexbox>
<Flexbox element="footer" height="60px">
Footer
</Flexbox>
</Flexbox>
);
}
}
Now Im getting Uncaught TypeError: this.state.dataSource.map is not a function
The problem was that I failed to initialize dataSource in the state, and then after that, I initialized it with a string instead of an empty array.
Was missing: dataSource: [] in this.setstate in the constructor.

Resources