day 19 has been published

pull/72/head
asabeneh 4 years ago
parent b4e23744d3
commit 556e47ab76

@ -0,0 +1,5 @@
# 30 Days of React App: Day 19
In the project directory, you can run to start the project
### `npm start`

@ -0,0 +1,84 @@
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import axios from 'axios'
const Country = ({
country: { name, capital, flag, languages, population, currency },
}) => {
const formatedCapital =
capital.length > 0 ? (
<>
<span>Capital: </span>
{capital}
</>
) : (
''
)
const formatLanguage = languages.length > 1 ? `Languages` : `Language`
console.log(languages)
return (
<div className='country'>
<div className='country_flag'>
<img src={flag} alt={name} />
</div>
<h3 className='country_name'>{name.toUpperCase()}</h3>
<div class='country_text'>
<p>{formatedCapital}</p>
<p>
<span>{formatLanguage}: </span>
{languages.map((language) => language.name).join(', ')}
</p>
<p>
<span>Population: </span>
{population.toLocaleString()}
</p>
<p>
<span>Currency: </span>
{currency}
</p>
</div>
</div>
)
}
class App extends Component {
state = {
data: [],
}
componentDidMount() {
this.fetchCountryData()
}
fetchCountryData = async () => {
const url = 'https://restcountries.eu/rest/v2/all'
try {
const response = await axios.get(url)
const data = await response.data
this.setState({
data,
})
} catch (error) {
console.log(error)
}
}
render() {
return (
<div className='App'>
<h1>React Component Life Cycle</h1>
<h1>Calling API</h1>
<div>
<p>There are {this.state.data.length} countries in the api</p>
<div className='countries-wrapper'>
{this.state.data.map((country) => (
<Country country={country} />
))}
</div>
</div>
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

@ -0,0 +1,496 @@
<div align="center">
<h1> 30 Days Of React: Fetch and Axios</h1>
<a class="header-badge" target="_blank" href="https://www.linkedin.com/in/asabeneh/">
<img src="https://img.shields.io/badge/style--5eba00.svg?label=LinkedIn&logo=linkedin&style=social">
</a>
<a class="header-badge" target="_blank" href="https://twitter.com/Asabeneh">
<img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/asabeneh?style=social">
</a>
<sub>Author:
<a href="https://www.linkedin.com/in/asabeneh/" target="_blank">Asabeneh Yetayeh</a><br>
<small> October, 2020</small>
</sub>
</div>
[<< Day 17](../17_React_Router/17_react_router.md) | [Day 19>>]()
![30 Days of React banner](../images/30_days_of_react_banner_day_18.jpg)
- [Fetch and Axios](#fetch-and-axios)
- [Fetch](#fetch)
- [Axios](#axios)
- [Exercises](#exercises)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 1](#exercises-level-1-1)
# Fetch and Axios
## Fetch
Currently, JavaScript provides a fetch API to make HTTP requests. Fetch might not be supported by all browsers therefore we have install addition package for browser supports. However, if we use Axios we do not need to use additional package for browser support. Axios code seems neater than fetch. In this section we will see the difference between fetch and axios. May be if you want to know the browser support of fetch you check out on [caniuse](https://caniuse.com/ciu/index) website. As of today, it has 95.62% browser support.
```js
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
const Country = ({
country: { name, capital, flag, languages, population, currency },
}) => {
const formatedCapital =
capital.length > 0 ? (
<>
<span>Capital: </span>
{capital}
</>
) : (
''
)
const formatLanguage = languages.length > 1 ? `Languages` : `Language`
console.log(languages)
return (
<div className='country'>
<div className='country_flag'>
<img src={flag} alt={name} />
</div>
<h3 className='country_name'>{name.toUpperCase()}</h3>
<div class='country_text'>
<p>{formatedCapital}</p>
<p>
<span>{formatLanguage}: </span>
{languages.map((language) => language.name).join(', ')}
</p>
<p>
<span>Population: </span>
{population.toLocaleString()}
</p>
<p>
<span>Currency: </span>
{currency}
</p>
</div>
</div>
)
}
class App extends Component {
state = {
data: [],
}
componentDidMount() {
const url = 'https://restcountries.eu/rest/v2/all'
fetch(url)
.then((response) => {
return response.json()
})
.then((data) => {
console.log(data)
this.setState({
data,
})
})
.catch((error) => {
console.log(error)
})
}
render() {
return (
<div className='App'>
<h1>React Component Life Cycle</h1>
<h1>Calling API</h1>
<div>
<p>There are {this.state.data.length} countries in the api</p>
<div className='countries-wrapper'>
{this.state.data.map((country) => (
<Country country={country} />
))}
</div>
</div>
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
We can implement async and await and make the above code short and clean.
```js
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
const Country = ({
country: { name, capital, flag, languages, population, currency },
}) => {
const formatedCapital =
capital.length > 0 ? (
<>
<span>Capital: </span>
{capital}
</>
) : (
''
)
const formatLanguage = languages.length > 1 ? `Languages` : `Language`
console.log(languages)
return (
<div className='country'>
<div className='country_flag'>
<img src={flag} alt={name} />
</div>
<h3 className='country_name'>{name.toUpperCase()}</h3>
<div class='country_text'>
<p>{formatedCapital}</p>
<p>
<span>{formatLanguage}: </span>
{languages.map((language) => language.name).join(', ')}
</p>
<p>
<span>Population: </span>
{population.toLocaleString()}
</p>
<p>
<span>Currency: </span>
{currency}
</p>
</div>
</div>
)
}
class App extends Component {
state = {
data: [],
}
componentDidMount() {
this.fetchCountryData()
}
fetchCountryData = async () => {
const url = 'https://restcountries.eu/rest/v2/all'
const response = await fetch(url)
const data = await response.json()
this.setState({
data,
})
}
render() {
return (
<div className='App'>
<h1>Fetching API using Fetch</h1>
<h1>Calling API</h1>
<div>
<p>There are {this.state.data.length} countries in the api</p>
<div className='countries-wrapper'>
{this.state.data.map((country) => (
<Country country={country} />
))}
</div>
</div>
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
If we use async and await we handle the error using try and catch. Let's apply a try catch block in the above code.
```js
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
const Country = ({
country: { name, capital, flag, languages, population, currency },
}) => {
const formatedCapital =
capital.length > 0 ? (
<>
<span>Capital: </span>
{capital}
</>
) : (
''
)
const formatLanguage = languages.length > 1 ? `Languages` : `Language`
console.log(languages)
return (
<div className='country'>
<div className='country_flag'>
<img src={flag} alt={name} />
</div>
<h3 className='country_name'>{name.toUpperCase()}</h3>
<div class='country_text'>
<p>{formatedCapital}</p>
<p>
<span>{formatLanguage}: </span>
{languages.map((language) => language.name).join(', ')}
</p>
<p>
<span>Population: </span>
{population.toLocaleString()}
</p>
<p>
<span>Currency: </span>
{currency}
</p>
</div>
</div>
)
}
class App extends Component {
state = {
data: [],
}
componentDidMount() {
this.fetchCountryData()
}
fetchCountryData = async () => {
const url = 'https://restcountries.eu/rest/v2/all'
try {
const response = await fetch(url)
const data = await response.json()
this.setState({
data,
})
} catch (error) {
console.log(error)
}
}
render() {
return (
<div className='App'>
<h1>Fetching API using Fetch</h1>
<h1>Calling API</h1>
<div>
<p>There are {this.state.data.length} countries in the api</p>
<div className='countries-wrapper'>
{this.state.data.map((country) => (
<Country country={country} />
))}
</div>
</div>
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
Now, let's see how to do the same API call using axios.
How can do fetch if we have multiple API two call ?
## Axios
Axios is a third party package and we need to install it using npm. It is the most popular way to make HTTP requests(GET, POST, PUT, PATCH, DELETE). In this example, we will cover only a get request.
```js
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import axios from 'axios'
const Country = ({
country: { name, capital, flag, languages, population, currency },
}) => {
const formatedCapital =
capital.length > 0 ? (
<>
<span>Capital: </span>
{capital}
</>
) : (
''
)
const formatLanguage = languages.length > 1 ? `Languages` : `Language`
console.log(languages)
return (
<div className='country'>
<div className='country_flag'>
<img src={flag} alt={name} />
</div>
<h3 className='country_name'>{name.toUpperCase()}</h3>
<div class='country_text'>
<p>{formatedCapital}</p>
<p>
<span>{formatLanguage}: </span>
{languages.map((language) => language.name).join(', ')}
</p>
<p>
<span>Population: </span>
{population.toLocaleString()}
</p>
<p>
<span>Currency: </span>
{currency}
</p>
</div>
</div>
)
}
class App extends Component {
state = {
data: [],
}
componentDidMount() {
const url = 'https://restcountries.eu/rest/v2/all'
axios
.get(url)
.then((response) => {
this.setState({
data: response.data,
})
})
.catch((error) => {
console.log(error)
})
}
render() {
return (
<div className='App'>
<h1>React Component Life Cycle</h1>
<h1>Calling API</h1>
<div>
<p>There are {this.state.data.length} countries in the api</p>
<div className='countries-wrapper'>
{this.state.data.map((country) => (
<Country country={country} />
))}
</div>
</div>
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
Let's also implement the axios fetching using async and await.
```js
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import axios from 'axios'
const Country = ({
country: { name, capital, flag, languages, population, currency },
}) => {
const formatedCapital =
capital.length > 0 ? (
<>
<span>Capital: </span>
{capital}
</>
) : (
''
)
const formatLanguage = languages.length > 1 ? `Languages` : `Language`
console.log(languages)
return (
<div className='country'>
<div className='country_flag'>
<img src={flag} alt={name} />
</div>
<h3 className='country_name'>{name.toUpperCase()}</h3>
<div class='country_text'>
<p>{formatedCapital}</p>
<p>
<span>{formatLanguage}: </span>
{languages.map((language) => language.name).join(', ')}
</p>
<p>
<span>Population: </span>
{population.toLocaleString()}
</p>
<p>
<span>Currency: </span>
{currency}
</p>
</div>
</div>
)
}
class App extends Component {
state = {
data: [],
}
componentDidMount() {
this.fetchCountryData()
}
fetchCountryData = async () => {
const url = 'https://restcountries.eu/rest/v2/all'
try {
const response = await axios.get(url)
const data = await response.data
this.setState({
data,
})
} catch (error) {
console.log(error)
}
}
render() {
return (
<div className='App'>
<h1>React Component Life Cycle</h1>
<h1>Calling API</h1>
<div>
<p>There are {this.state.data.length} countries in the api</p>
<div className='countries-wrapper'>
{this.state.data.map((country) => (
<Country country={country} />
))}
</div>
</div>
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
As you have seen, there is no much difference between fetch and axios. But I recommend you to use more axios than fetch because of browser support and easy of use.
# Exercises
## Exercises: Level 1
1. What is HTTP request?
2. What are the most common HTTP requests?
3. What is fetch?
4. What is axios?
5. What is the difference between fetch and axios?
6. Do you prefer fetch to axios for make HTTP requests?
## Exercises: Level 1
1. Find the average metric weight and life span of cats in the following [API](https://api.thecatapi.com/v1/breeds). There are 67 breeds of cats in API.
🎉 CONGRATULATIONS ! 🎉
[<< Day 17](../17_React_Router/17_react_router.md) | [Day 19>>]()

@ -1,303 +0,0 @@
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import {
BrowserRouter as Router,
Route,
Switch,
NavLink,
Redirect,
Prompt,
} from 'react-router-dom'
// Home component
const Home = (props) => <h1>Welcome Home</h1>
// About component
const About = (props) => <h1>About Us</h1>
// Contact component
const Contact = (props) => <h1>Contact us</h1>
// Challenge component
const challenges = [
{
name: '30 Days Of Python',
description:
'30 Days of Python challenge is a step by step guide to learn Python in 30 days.',
status: 'completed',
days: 30,
level: 'Beginners to Advanced',
duration: '20 Nov 2019 - 20 Dec 2019',
slug: 'pyhton',
url:
'https://github.com/https://https://github.com/Asabeneh/30-Days-Of-Python.com/Asabeneh/30-Days-Of-JavaScript/30-Days-Of-React',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
{
name: '30 Days Of JavaScript',
description:
'30 Days of JavaScript challenge is a step by step guide to learn JavaScript in 30 days.',
status: 'completed',
days: 30,
level: 'Beginners to Advanced',
duration: '1 Jan 2020 - 30 Jan 2020',
slug: 'javascript',
url: 'https://github.com/Asabeneh/30-Days-Of-JavaScript',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
{
name: '30 Days Of React',
description:
'30 Days of React challenge is a step by step guide to learn React in 30 days.',
status: 'ongoing',
days: 30,
level: 'Beginners to Advanced',
duration: '1 Oct 2020- 30 Oct 2020',
slug: 'react',
url: 'https://github.com/Asabeneh/30-Days-Of-React',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
{
name: '30 HTML and CSS',
description:
'30 Days of HTML and CSS challenge is a step by step guide to learn HTML and CSS in 30 days.',
status: 'coming',
days: 30,
level: 'Beginners to Advanced',
duration: '',
slug: 'html-and-css',
url: '',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
{
name: '30 ReactNative',
description:
'30 Days of ReactNative challenge is a step by step guide to learn ReactNative in 30 days.',
status: 'coming',
days: 30,
level: 'Beginners to Advanced',
duration: '',
slug: 'reactnative',
url: '',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
{
name: '30 Data Analysis',
description:
'30 Days of Data Analysis challenge is a step by step guide to learn about data, data visualization and data analysis in 30 days.',
status: 'coming',
days: 30,
level: 'Beginners to Advanced',
duration: '',
slug: 'data-analysis',
url: '',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
{
name: '30 Machine Learning',
description:
'30 Days of Machine learning challenge is a step by step guide to learn data cleaning, machine learning models and predictions in 30 days.',
status: 'coming',
days: 30,
level: 'Beginners to Advanced',
duration: '',
slug: 'machine-learning',
url: '',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
]
const Challenge = ({
challenge: {
name,
description,
status,
days,
level,
duration,
author: { firstName, lastName },
},
}) => (
<div>
<h1>{name}</h1>
<p>{level}</p>
<p>
Author: {firstName} {lastName}
</p>
{duration && (
<>
{' '}
<small>{duration}</small> <br />
</>
)}
<small>Number of days: {days}</small>
<p>{description}</p>
</div>
)
const Challenges = (props) => {
const path = props.location.pathname
const slug = path.split('/').slice(path.split('/').length - 1)[0]
const challenge = challenges.find((challenge) => challenge.slug === slug)
return (
<div>
<h1>30 Days Of React Challenge</h1>
<ul>
{challenges.map(({ name, slug }) => (
<li key={slug}>
<NavLink to={`/challenges/${slug}`}>{name}</NavLink>
</li>
))}
</ul>
<Switch>
<Route
exact
path={'/challenges'}
component={() => <h1>Choose any of the challenges</h1>}
/>
<Route
path={path}
component={(props) => <Challenge challenge={challenge} />}
/>
</Switch>
</div>
)
}
const NotFound = (props) => <h1>The page your looking for not found</h1>
const Navbar = ({ username }) => (
<ul>
<li>
<NavLink to='/'>Home</NavLink>
</li>
<li>
<NavLink to='/about'>About</NavLink>
</li>
<li>
<NavLink to='/contact'>Contact</NavLink>
</li>
<li>
<NavLink to={`/user/${username}`}>User</NavLink>
</li>
<li>
<NavLink to='/challenges'>Challenges</NavLink>
</li>
</ul>
)
const User = ({ match, isLoggedIn, handleLogin }) => {
const username = match.params.username
return (
<div>
{isLoggedIn ? (
<>
<h1>Welcome {username} to the challenge</h1>
<small>Now, you can navigate through all the challenges</small> <br />
</>
) : (
<p>Please login in to access the challenges </p>
)}
<button onClick={handleLogin}>{isLoggedIn ? 'Logout' : 'Login'}</button>
</div>
)
}
const Welcome = ({ handleLogin, isLoggedIn }) => {
return (
<div>
{isLoggedIn ? 'Welcome to the challenge' : <p>Please login in </p>}
<button onClick={handleLogin}>{isLoggedIn ? 'Logout' : 'Login'}</button>
</div>
)
}
class App extends Component {
state = {
isLoggedIn: false,
firstName: 'Asabeneh',
}
handleLogin = () => {
this.setState({
isLoggedIn: !this.state.isLoggedIn,
})
}
render() {
return (
<Router>
<div className='App'>
<Navbar username={this.state.firstName} />
<Prompt
message={({ pathname }) => {
return this.state.isLoggedIn &&
pathname.includes('/user/Asabeneh')
? 'Are you sure you want to logout?'
: true
}}
/>
<Switch>
<Route path='/about' component={About} />
<Route path='/contact' component={Contact} />
<Route
path='/user/:username'
component={(props) => (
<User
{...props}
isLoggedIn={this.state.isLoggedIn}
handleLogin={this.handleLogin}
/>
)}
/>
<Route
path='/login'
component={(props) => (
<Welcome
{...props}
isLoggedIn={this.state.isLoggedIn}
handleLogin={this.handleLogin}
/>
)}
/>
<Route
path='/challenges'
component={(props) => {
return this.state.isLoggedIn ? (
<Challenges {...props} />
) : (
<Redirect to='/user/asabeneh' />
)
}}
/>
<Route exact path='/' component={Home} />
<Route component={NotFound} />
</Switch>
</div>
</Router>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

@ -14,32 +14,22 @@
</div>
[<< Day 17](../17_React_Router/17_react_router.md) | [Day 19>>]()
[<< Day 18](../18_Fetch_And_Axios/18_fetch_axios.md) | [Day 20>>]()
![30 Days of React banner](../images/30_days_of_react_banner_day_18.jpg)
![30 Days of React banner](../images/30_days_of_react_banner_day_19.jpg)
- [Projects](#projects)
- [Exercises](#exercises)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
- [Exercises: Level 3](#exercises-level-3)
# Projects
Congratulations for making it to this far. Now, you have a solid understanding of React. I believe we have cover most of the feature of React and your are ready to work on projects. What we have cover so far is the old version of React. Starting from Day 20 we will learn React Hooks. In the next three days you will work on projects only.
Congratulations for making it to this far. Now, you have a solid understanding of React. I believe we have covered most important features of React and your are ready to work on projects. What we have covered so far is the old version of React. Starting from Day 20, we will learn React Hooks. In the next three days you will work on projects only.
# Exercises
## Exercises: Level 1
## Exercises: Level 2
coming
## Exercises: Level 3
coming
🎉 CONGRATULATIONS ! 🎉
[<< Day 17](../17_React_Router/17_react_router.md) | [Day 19>>]()
[<< Day 18](../18_Fetch_And_Axios/18_fetch_axios.md) | [Day 20>>]()

@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

@ -0,0 +1,34 @@
{
"name": "30-days-of-react",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

@ -0,0 +1,111 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://fonts.googleapis.com/css?family=Montserrat:300,400,500|Roboto:300,400,500&display=swap"
rel="stylesheet"
/>
<meta
name="description"
content="Web site created using create-react-app"
/>
<title>30 Days Of React App</title>
<style>
/* == General style === */
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
line-height: 1.5;
font-family: 'Montserrat';
font-weight: 300;
color: black;
}
.root {
min-height: 100%;
position: relative;
}
.header-wrapper,
.main-wrapper,
.footer-wrapper {
width: 85%;
margin: auto;
}
.header-wrapper,
.main-wrapper {
padding: 10px;
margin: 2px auto;
}
h1 {
font-size: 70px;
font-weight: 300;
}
h2,
h3 {
font-weight: 300;
}
header {
background-color: #61dbfb;
padding: 25;
padding: 10px;
}
main {
padding: 10px;
padding-bottom: 60px;
/* Height of the footer */
}
ul {
margin-left: 15px;
}
ul li {
list-style: none;
}
footer {
position: absolute;
bottom: 0;
width: 100%;
height: 60px;
/* Height of the footer */
background: #6cf;
}
.footer-wrapper {
font-weight: 400;
text-align: center;
line-height: 60px;
}
.user-card {
margin-top: 10px;
}
.user-card > img {
border-radius: 50%;
width: 14%;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
</html>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,13 @@
export const tenHighestPopulation = [
{ country: 'World', population: 7693165599 },
{ country: 'China', population: 1377422166 },
{ country: 'India', population: 1295210000 },
{ country: 'United States of America', population: 323947000 },
{ country: 'Indonesia', population: 258705000 },
{ country: 'Brazil', population: 206135893 },
{ country: 'Pakistan', population: 194125062 },
{ country: 'Nigeria', population: 186988000 },
{ country: 'Bangladesh', population: 161006790 },
{ country: 'Russian Federation', population: 146599183 },
{ country: 'Japan', population: 126960000 },
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

@ -0,0 +1,84 @@
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import axios from 'axios'
const Country = ({
country: { name, capital, flag, languages, population, currency },
}) => {
const formatedCapital =
capital.length > 0 ? (
<>
<span>Capital: </span>
{capital}
</>
) : (
''
)
const formatLanguage = languages.length > 1 ? `Languages` : `Language`
console.log(languages)
return (
<div className='country'>
<div className='country_flag'>
<img src={flag} alt={name} />
</div>
<h3 className='country_name'>{name.toUpperCase()}</h3>
<div class='country_text'>
<p>{formatedCapital}</p>
<p>
<span>{formatLanguage}: </span>
{languages.map((language) => language.name).join(', ')}
</p>
<p>
<span>Population: </span>
{population.toLocaleString()}
</p>
<p>
<span>Currency: </span>
{currency}
</p>
</div>
</div>
)
}
class App extends Component {
state = {
data: [],
}
componentDidMount() {
this.fetchCountryData()
}
fetchCountryData = async () => {
const url = 'https://restcountries.eu/rest/v2/all'
try {
const response = await axios.get(url)
const data = await response.data
this.setState({
data,
})
} catch (error) {
console.log(error)
}
}
render() {
return (
<div className='App'>
<h1>React Component Life Cycle</h1>
<h1>Calling API</h1>
<div>
<p>There are {this.state.data.length} countries in the api</p>
<div className='countries-wrapper'>
{this.state.data.map((country) => (
<Country country={country} />
))}
</div>
</div>
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

File diff suppressed because it is too large Load Diff

@ -40,7 +40,10 @@
|15|[Third Party Packages](./15_Third_Party_Packages/15_third_party_packages.md)|
|16|[Higher Order Components](./16_Higher_Order_Component/16_higher_order_component.md)|
|17|[React Router](./17_React_Router/17_react_router.md)|
|17|[Projects](./18_projects/18_projects.md)|
|18|[Fetch versus Axios](./18_Fetch_And_Axios/18_fetch_axios.md)|
|19|[Projects](./19_projects/19_projects.md)|
|20|[Projects]()|
|21|[Hooks]()|

Loading…
Cancel
Save