Issue with getting an object to return, Weather App

Creating a weather app, and I am trying to break down the hourly data received. I can't figure out how to return it from its object it since I am using a for each loop. I am able to console.log the correct data while testing, but can't figure out how to pass it/return. Im taking the function that creates the hourly data and trying to pass it into a state.hourly object. When I log the state.hourly i get undefined. Here is a pen and repo which ever is easier to view. https://codepen.io/bsups/pen/ExLoVdb?editors=0010 https://github.com/bsupinski/weather-app
Brandon
CodePen
ExLoVdb
...
GitHub
GitHub - bsupinski/weather-app: weather app
weather app. Contribute to bsupinski/weather-app development by creating an account on GitHub.
10 Replies
Joao
Joao•3y ago
forEach does not return anything, it simply loops over each item in the array and runs the callback function. You can use map instead, which will return an array
const createCurrentHourlyForecast = (data) => {
const { forecast } = data;
return forecast.forecastday[0].hour.map((hour) => {
if (hour.time > state.location.currDayTime) {
return {
hourTemp_f: hour.temp_f,
};
}
});
};
const createCurrentHourlyForecast = (data) => {
const { forecast } = data;
return forecast.forecastday[0].hour.map((hour) => {
if (hour.time > state.location.currDayTime) {
return {
hourTemp_f: hour.temp_f,
};
}
});
};
Errtu
ErrtuOP•3y ago
Awesome thank you. Why does it allow return being used twice? Or does the 2nd return get passed to first?
Joao
Joao•3y ago
Exactly, the second return statement belongs to the map callback function. Whatever you return there, it'll be placed on the resulting array at that particular index. The first return statement belongs to the cretaeCurrentHourlyForecast. For example you could also do:
const createCurrentHourlyForecast = (data) => {
const { forecast } = data;
const hourlyForecast = forecast.forecastday[0].hour.map((hour) => {
if (hour.time > state.location.currDayTime) {
return {
hourTemp_f: hour.temp_f,
};
}
});

return hourlyForecast;
};
const createCurrentHourlyForecast = (data) => {
const { forecast } = data;
const hourlyForecast = forecast.forecastday[0].hour.map((hour) => {
if (hour.time > state.location.currDayTime) {
return {
hourTemp_f: hour.temp_f,
};
}
});

return hourlyForecast;
};
Errtu
ErrtuOP•3y ago
I really appreciate the help and letting me know I understood correctly. This is what I came up with to also filter out undefined that would come back const createCurrentHourlyForecast = (data) => { const { forecast } = data; const hoursLeftInDay = forecast.forecastday[0].hour.filter((hour) => { if (hour.time > state.location.currDayTime) { return hour; } }); return hoursLeftInDay.map((hour) => { return { hourTemp_f: hour.temp_f, }; }); };
Joao
Joao•3y ago
I thought you might get some undefined values but wasn't sure if you actually needed them. In that case, as you discovered, using filter is a much better approach:
const createCurrentHourlyForecast = (data) => {
const { forecast } = data;
const hoursLeftInDay = forecast.forecastday[0].hour.filter((hour) => {
return hour.time > state.location.currDayTime;
});
};
const createCurrentHourlyForecast = (data) => {
const { forecast } = data;
const hoursLeftInDay = forecast.forecastday[0].hour.filter((hour) => {
return hour.time > state.location.currDayTime;
});
};
With filter, you need to return a boolean. If it's true, then the element will be returned otherwise it won't.
Joao
Joao•3y ago
const createCurrentHourlyForecast = (data) => {
const { forecast } = data;
return forecast.forecastday[0].hour.filter(hour => hour.time > state.location.currDayTime);
};
const createCurrentHourlyForecast = (data) => {
const { forecast } = data;
return forecast.forecastday[0].hour.filter(hour => hour.time > state.location.currDayTime);
};
It can be shorten a little more like this. Btw wrap your code in triple quotes to make the code block easier to read:
Errtu
ErrtuOP•3y ago
Awesome, thank you!
const createCurrentHourlyForecast = (data) => {
const { forecast } = data;
return (hoursLeftInDay = forecast.forecastday[0].hour.filter(
(hour) => hour.time > state.location.currDayTime
)).map((hour) => {
return {
hourTemp_f: hour.temp_f,
};
});
};
const createCurrentHourlyForecast = (data) => {
const { forecast } = data;
return (hoursLeftInDay = forecast.forecastday[0].hour.filter(
(hour) => hour.time > state.location.currDayTime
)).map((hour) => {
return {
hourTemp_f: hour.temp_f,
};
});
};
Joao
Joao•3y ago
While we are at it why not go for reduce? 😄 Then you can combine both methods in one.
const createCurrentHourlyForecast = (data) => {
const { forecast } = data;

const hourlyForecast = forecast.forecastday[0].hour.reduce((acc, hour) => {
if (hour.time > state.location.currDayTime) {
acc.push({ hourTemp_f: hour.temp_f });
}
return acc;
}, []);

return hourlyForecast;
};
const createCurrentHourlyForecast = (data) => {
const { forecast } = data;

const hourlyForecast = forecast.forecastday[0].hour.reduce((acc, hour) => {
if (hour.time > state.location.currDayTime) {
acc.push({ hourTemp_f: hour.temp_f });
}
return acc;
}, []);

return hourlyForecast;
};
Remember that making things short can hurt readability, and most often than not that's more important. The reduce method is often recommended against because it can get quite tricky but this is just to show you. If I had to do this myself I would probably prefer your solution, combining filter and then map which makes it very clear what's happening.
Errtu
ErrtuOP•3y ago
That's something I actually struggle with shot vs readability, finding that nice balance.
MarkBoots
MarkBoots•3y ago
don't think the readability hurts here. It's just a reduce. Maybe the method itself is a bit 'scary' for some, but this is how it works
Want results from more Discord servers?
Add your server