Reputation: 509
'm trying to map some data that I have stored in an array (the screenshot below), but I can't seem to access it, because it is loaded asynchronously. How could I await the data? Is there a way to do it in the render function?
render() {
return (
{this.state.serials.map((number) => {
return number.s && number.s.length?
(
<h2 > {number.s[0].a}</h2>
) : null
})}
)
}
This is componentDidMount() where I get my data:
componentDidMount()
const uid = this.state.user.uid;
const gatewayRef = db.ref(uid + '/gateways');
gatewayRef.on('value', (gateways_nums) => {
const serialsArr = [];
gateways_nums.forEach((gateway_num) => {
const serialRef = db.ref('gateways/' + gateway_num.val()['gateway'])
const last_temps =[];
serialRef.on('value', (serials)=>{
const ser = []
serials.forEach((serial)=>{
ser.push(serial.val()['serial'])
})
last_temps.push({a: gateway_num.val()['gateway'], b: ser})
})
serialsArr.push({s:last_temps})
});
this.setState({serials:serialsArr})
});
}
I would really appreciate any help!
Upvotes: 2
Views: 56
Reputation: 509
I managed to get it working by changing the algorithm a bit. With this code there is no need for awating data:
componentDidMount() {
const uid = this.state.user.uid;
const serialRef = db.ref(uid + '/gateways');
serialRef.on('value', (serial_numbers) => {
const serials = [];
serial_numbers.forEach((serial_number) => {
const za = serial_number.val()['gateway'];
const last_temps = [];
const tempRef = db.ref('gateways/' + za);
tempRef.orderByChild("serial").on('value', (temps) => {
const temparray = [];
temps.forEach((temp) => {
temparray.push(temp.val());
})
const last_temp = temparray;
last_temps.push({ l: last_temp, za });
this.setState({ last_temps: last_temps })
})
serials.push({ s: last_temps });
});
this.setState({ serials: serials });
});
}
Upvotes: 0
Reputation: 3639
Try this:
render() {
if(!this.state.serials) {
// Ideally you should draw some loading spinner here
// to indicate that data is not ready yet. But for a quick
// solution you can just draw nothing
return null
}
// Also "return ({ this.state.serials.map() })" is not valid syntax
// you either need to return just an array without using braces, or
// use some JSX tag and put braces inside of it
return (
<div>
{this.state.serials.map(serial => ...)}
</div>
)
}
Speaking of invalid syntax with braces, you could also do
return this.state.serials.map(serial => ...)
Or (better)
return (
<>
{this.state.serials.map(serial => ...)}
</>
)
If you don't want an extra div around your data
Upvotes: 2