In this recap project, you'll work together with a partner: you'll create an app that fetches a weather object from an API and conditionally picks activities from a list to display as suggestions. You'll need to implement a feature that allows you to add more suggestions to the list of activities and also allows you to delete suggestions.
The way this app is going to handle data is a basic example of CRUD operations. CRUD stands for Create, Read, Update, and Delete. These operations are the main features every app needs.
Please note: the focus of this challenge is on React logic (and not on design), which is why the wireframes only have a very basic styling. Due to the given timeframe, you can consider styling the app as bonus task at the very end ;).
Built this project together with a partner in pair programming:
- share a single workstation (one screen, keyboard, and mouse);
- one partner is the "driver" and writes the code;
- the other is called "navigator" and focusses more on the overall direction of the application;
- set a timer (30 minutes is a good amount of time) and change roles regularly.
We are going to fetch all necessary information about the weather from a REST API specifically designed for this project. Check out the Weather API. You find all the information you need in the docs.
There is no template or starter code, so you can start completely fresh! Please use
create-react-app
to create a new project.
The sequence of the tasks described below is a good example for how to start writing an app.
💡 Because we need data to work with, we usually want to start with the C in CRUD. In this instance, adding a form that handles creating the data for our activities.
Being able to create new data is a good starting point for an app, so the first step is to create a form component to add a new activity.
-
Clean the app from everything which you don't need for a fresh start.
-
Write a
Form
component which- contains a heading
- has two input fields (name of activity, checkbox whether it is a good- or bad-weather activity) with appropriate labels and
- a submit button;
- it receives a prop called
onAddActivity
.
-
Handle the submit event:
-
Extract the submitted data as an object with the keys
name
andisForGoodWeather
and their respective values.- Hint: To get the boolean value of a checkbox, use
.checked
.
- Hint: To get the boolean value of a checkbox, use
-
Call
onAddActivity
and pass it the data object as argument.
-
-
After submitting, reset the form and focus the first input field.
-
Switch to the App.js and
- create a state for
activities
, - write a function
handleAddActivity
which accepts a new activity object as parameter and adds this object to theactivities
state - please add a unique id to every new activity object; you can use uid to do so.
- create a state for
-
Pass
handleAddActivity
to the Form component; make sure to use the correct prop name.
Use this wireframe as a reference:
🎉 Congratulations, you can now add new activities, including whether they can be done in good or bad weather!
By now, you can add new activities, but they are not yet displayed. Let's fix this.
- Write a
List
component which renders a list with list items for each activity in theactivities
state. - Make the state persistent in local storage.
Use this wireframe as a reference:
Currently, the list displays all activities, regardless of whether they are good or bad weather activities. The main purpose of the app, however, is to show activities depending on the current (good / bad) weather fetched from an API, so the list needs to be filtered.
- In the App.js, add a variable
const isGoodWeather = true
.- Note: For reasons of simplicity (i.e. it will be replaced in the next task anyway), we will use a hard coded variable to imitate good or bad weather for now.
- Filter the
activities
for those whose keyisForGoodWeather
is equal to the globalisGoodWeather
variable. - Instead of all
activities
, pass the filtered activities to theList
component. - In the List component, add a headline depending on the global
isGoodWeather
variable.
Use this wireframe as reference:
Refactor the code so that the "random" weather does not depend on a variable you set yourself, but on the answer from our weather API.
- Replace the global
isGoodWeather
variable from the previous task with a new state forweather
. - Fetch the weather API on initial render only.
- The
weather
state should equal the response you receive from the API. - Advanced note: The API has some more specific endpoints to test your application.
- The
- In the App.js, add a heading to display the condition emoji and the temperature.
Use this wireframe as reference:
- In the List component, add a delete button for each list item.
- The List component needs to receive a new prop called
onDeleteActivity
;- pass it to the delete button as onClick prop;
- pass the activity's id to
onDeleteActivity
as argument.
- In the App.js, write a function
handleDeleteActivity
, which accepts an id as parameter. The function should filter theactivities
state and keep all objects except the one with the given id.- Pass
handleDeleteActivity
to the List component asonDeleteActivity
prop.
- Pass
Use this wireframe as reference:
Fetching weather only on initial render is not really useful to stay up-to-date. Refactor your code so that the fetch is done every 5 seconds. Make sure to clear the timer when the component unmounts.