Title: if statement after looping through json in React Native
Tags: javascript;json;react-native
Question: I am creating a weather app with react native for fun. I am using an api to get the weather information which is stored as json.
I would like to be able to display the hourly weather based on what time of the day it is.
export default class App extends React.Component {
constructor (props) {
super(props);
this.state = {
isLoading: true,
componentDidMount() {
const fetch = require('node-fetch');
fetch('https://api.weatherapi.com/v1/forecast.json', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}).then((response) =&gt; response.json())
.then((responseJson) =&gt; {
console.log(responseJson);
this.setState({
isLoading: false,
dataSource: responseJson,
})
console.log(responseJson.forecast.forecastday[0].hour[0].time.split(" ")[1]);
const time = responseJson.location.localtime.split(" ")[1];
}).catch((error) =&gt; {
console.error(error);
});
render() {
if (this.state.isLoading) {
return (
<View style={{flex: 1, paddingTop: 20}}&gt;
<ActivityIndicator /&gt;
</View&gt;
return (
<View style={{flex:1, paddingTop: 20}}&gt;

<Text style={styles.text}&gt;{this.state.dataSource.location.name}</Text&gt;
<Text style={styles.mainText}&gt;{this.state.dataSource.current.condition.text}</Text&gt;
<Text style={styles.tempText}&gt;{this.state.dataSource.current.temp_c + '℃'}</Text&gt;
<View style={{flex:1, flexDirection: 'row', textAlign: 'center', paddingLeft: 90}}&gt;
<Text style={styles.maxTempText}&gt;{'H: ' + this.state.dataSource.forecast.forecastday[0].day.maxtemp_c + '℃'}</Text&gt;
<Text style={styles.maxTempText}&gt;{'L: ' + this.state.dataSource.forecast.forecastday[0].day.mintemp_c + '℃'}</Text&gt;
</View&gt;
</View&gt;
);
const myMainTime = () =&gt; {
const mainTime = this.state.dataSource.forecast.forecastday[0].hour[0].time.split(" ")[1];
{this.state.dataSource.forecast.forecastday[0].hour.map((item) =&gt; (
if ( mainTime &gt;= time ) {
return (

<ScrollView horizontal={true}&gt;
<View style={{flex:1, flexDirection: 'row', textAlign: 'center'}}&gt;
<View&gt;
<Text&gt;{item.time.split(" ")[1]}</Text&gt;
<Image source={{url: "https:" + item.condition.icon}}
style={{ width: 50, height: 50, paddingBottom: 10, alignItems: 'center',  justifyContent: 'center' }}
/&gt;
<Text&gt;{item.temp_c + '℃'}</Text&gt;
</View&gt;
))}
</View&gt;
</ScrollView&gt;
)
Here is the json
"location": {
"name": "New York",
"region": "New York",
"country": "United States of America",
"lat": 40.71,
"lon": -74.01,
"tz_id": "America/New_York",
"localtime_epoch": 1623928876,
"localtime": "2021-06-17 7:21"
},
"current": {
"last_updated_epoch": 1623928500,
"last_updated": "2021-06-17 07:15",
"temp_c": 15.6,
"temp_f": 60.1,
"is_day": 1,
"condition": {
"text": "Sunny",
"icon": "//cdn.weatherapi.com/weather/64x64/day/113.png",
"code": 1000
},
"wind_mph": 4.3,
"wind_kph": 6.8,
"wind_degree": 310,
"wind_dir": "NW",
"pressure_mb": 1016.0,
"pressure_in": 30.5,
"precip_mm": 0.0,
"precip_in": 0.0,
"humidity": 46,
"cloud": 0,
"feelslike_c": 15.6,
"feelslike_f": 60.1,
"vis_km": 10.0,
"vis_miles": 6.0,
"uv": 1.0,
"gust_mph": 8.7,
"gust_kph": 14.0
},
"forecast": {
"forecastday": [
{
"date": "2021-06-17",
"date_epoch": 1623888000,
"day": {
"maxtemp_c": 27.0,
"maxtemp_f": 80.6,
"mintemp_c": 15.9,
"mintemp_f": 60.6,
"maxwind_mph": 8.3,
"maxwind_kph": 13.3,
"totalprecip_mm": 0.0,
"totalprecip_in": 0.0,
"avgvis_km": 10.0,
"avgvis_miles": 6.0,
"avghumidity": 35.0,
"daily_will_it_rain": 0,
"daily_chance_of_rain": "0",
"daily_will_it_snow": 0,
"daily_chance_of_snow": "0",
"condition": {
"text": "Partly cloudy",
"icon": "//cdn.weatherapi.com/weather/64x64/day/116.png",
"code": 1003
},
"uv": 7.0
},
"astro": {
"sunrise": "05:25 AM",
"sunset": "08:30 PM",
"moonrise": "12:16 PM",
"moonset": "01:02 AM",
"moon_phase": "Waxing Gibbous",
"moon_illumination": "55"
},
"hour": [
{
"time_epoch": 1623902400,
"time": "2021-06-17 00:00",
"temp_c": 17.8,
"temp_f": 64.0,
"is_day": 0,
"condition": {
"text": "Partly cloudy",
"icon": "//cdn.weatherapi.com/weather/64x64/night/116.png",
"code": 1003
},
"wind_mph": 9.6,
"wind_kph": 15.5,
"wind_degree": 326,
"wind_dir": "NNW",
"pressure_mb": 1014.0,
"pressure_in": 30.4,
"precip_mm": 0.0,
"precip_in": 0.0,
"humidity": 43,
"cloud": 12,
"feelslike_c": 17.8,
"feelslike_f": 64.0,
"windchill_c": 17.8,
"windchill_f": 64.0,
"heatindex_c": 17.8,
"heatindex_f": 64.0,
"dewpoint_c": 5.1,
"dewpoint_f": 41.2,
"will_it_rain": 0,
"chance_of_rain": "0",
"will_it_snow": 0,
"chance_of_snow": "0",
"vis_km": 10.0,
"vis_miles": 6.0,
"gust_mph": 13.0,
"gust_kph": 20.9,
"uv": 1.0
},
{
"time_epoch": 1623906000,
"time": "2021-06-17 01:00",
"temp_c": 16.9,
"temp_f": 62.4,
"is_day": 0,
"condition": {
"text": "Partly cloudy",
"icon": "//cdn.weatherapi.com/weather/64x64/night/116.png",
"code": 1003
},
"wind_mph": 8.7,
"wind_kph": 14.0,
"wind_degree": 321,
"wind_dir": "NW",
"pressure_mb": 1014.0,
"pressure_in": 30.4,
"precip_mm": 0.0,
"precip_in": 0.0,
"humidity": 44,
"cloud": 21,
"feelslike_c": 16.9,
"feelslike_f": 62.4,
"windchill_c": 16.9,
"windchill_f": 62.4,
"heatindex_c": 16.9,
"heatindex_f": 62.4,
"dewpoint_c": 4.6,
"dewpoint_f": 40.3,
"will_it_rain": 0,
"chance_of_rain": "0",
"will_it_snow": 0,
"chance_of_snow": "0",
"vis_km": 10.0,
"vis_miles": 6.0,
"gust_mph": 11.6,
"gust_kph": 18.7,
"uv": 1.0
},
}
I  would like to loop through the hourly weather and then if the current time is the same or greater than the time in the json I would like the display the information within the app.
Is there any way of doing this?
Comment: the hourly weather under forecastday and then hour

Comment: thanks but not sure you have understood what i am asking. I want to only display the information if the time is equal or greater than the current time

Comment: What part of the json do you want to compare?

Comment: the hour part of the json has many values under it. You either need to select some (or all) specific parts under hour and then compare them or you can just use if(previousState !== newState){
//change state
to change the state based on id the weather has changed. I'd be happy to answer if you be more specicific.


Here is another answer: Looking at the JSON you get back from the api, it returns something called &quot;time_epoch&quot; for each hour (info), which is also what is returned when you run Date.now in js, info.
Not sure about the rest of your code, but making this one change will check for what you want here:
{this.state.dataSource.forecast.forecastday[0].hour.map((item) =&gt; (
if ( Date.now() &gt;= item.time_epoch ) {
return (
Comment for this answer: @becky, you should add that complete if clause insdie curly braces
example :
....map((item)=> { if(rest of code){ return rest of code}})

Here is another answer: If you don't need the past data, you can filter the array with current time.
const today = moment().startOf('day').valueOf() // not sure if the date_epoch is utc or not, if it is, you need to parse it to utc time
const days = forecast.forecastday
.filter(day =&gt; day.date_epoch * 1000 &gt;= today)
.map(futureDay =&gt; {
if(futureDay.date_epoch * 1000 === today) {
return {
...futureDay,
hour: futureDay.hour.filter(hour =&gt; hour.time_epoch * 1000 &gt;= Date.now())
}
}
return futureDay
}
Comment for this answer: what kind of errors are you facing. it is just a pseudocode.

Here is another answer: If will not work because you are not using function body,
if you want to use provide function body inside map and use or do like below.
this.state.dataSource.forecast.forecastday[0].hour.map((item) =&gt;
Date.now() &gt;= item.time_epoch ? (
<ScrollView horizontal={true}&gt;
<View style={{ flex: 1, flexDirection: &quot;row&quot;, textAlign: &quot;center&quot; }}&gt;
<View&gt;
<Text&gt;{item.time.split(&quot; &quot;)[1]}</Text&gt;
<Image
source={{ url: &quot;https:&quot; + item.condition.icon }}
style={{
width: 50,
height: 50,
paddingBottom: 10,
alignItems: &quot;center&quot;,
justifyContent: &quot;center&quot;,
}}
/&gt;
<Text&gt;{item.temp_c + &quot;℃&quot;}</Text&gt;
</View&gt;
):null );
</View&gt;
</ScrollView&gt;
) : null
Comment for this answer: I'm getting this error " ERROR  [Error: Text strings must be rendered within a  component.]"
Comment for this answer: ERROR [Error: Text strings must be rendered within a  component.]"
Comment for this answer: it seems to point to this line ""
Comment for this answer: I found the problem, I needed to put the information in it's own function. But when I do this it doesn't show anything in the app
Comment for this answer: I think the line " this.state.dataSource.forecast.forecastday[0].hour.map((item) =>" only works after the view
Comment for this answer: @becky I think issue is because of any value is coming as undefined/null not sure which one `null/undefined`. Are you sure, that you are getting all the values.

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 3, 'CommentCount': 4, 'ContentLicense': 'CC BY-SA 4.0', 'CreationDate': '2021:00:06/17/21', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<javascript><json><react-native>', 'Title': 'if statement after looping through json in React Native', 'ViewCount': 210, 'id': 68018360, 'user_AboutMe': None, 'user_AccountId': 10576213.0, 'user_DisplayName': 'becky', 'user_Reputation': 153.0, 'user_Views': 118.0, 'user_id': 12339109.0}}