Я выполнил свой проект Javascript по новейшим случаям covid-19 по всему миру.

Я получил свою информацию из внешнего API, веб-сайта, который я нашел после нескольких поисков в Google, под названием https://rapidapi.com/.

Я нашел api со 100% -ным успехом и с галочкой, которая читает проверено, и пошел на это ..

это фрагмент запроса GET из моего файла frontend / index.js моего проекта Javascript…

function myApi() {
fetch("https://covid-193.p.rapidapi.com/statistics", {
"method": "GET",
"headers": {
"x-rapidapi-host": "covid-193.p.rapidapi.com",
"x-rapidapi-key": "9d691e50d2msh4aa205c2ff027f5p10f338jsn0e4e7c874dc3"
}
})
.then(res => res.json())
.then(value => {
Search.allCases(value)
;
})
.catch(err => {
console.log(err);
});
}

Все поступающие данные вызываются функцией allCases (), которая принимает данные (значение) в качестве аргумента.

Search.allCases(value)

allCases () - это статическая функция, расположенная в файле «frontend / search.js», также известном как класс Search .. (я объясню класс Search позже ..)

static allCases(value){
const val = value.response.reduce((acc, val) => {
return val.cases.total + acc
}, 0)
h3().innerText = val
}
a snippet from my “frontend/search.js” file

вызов static перед функцией эквивалентен вызову self

в данном случае self является классом Search.

Я вызываю метод .reduce (), чтобы просуммировать все наблюдения, чтобы отобразить сумму всех наблюдений по всему миру.

← фрагмент того, как allCases () выглядит на сайте

примечание: я также сделал свой собственный css ... даже несмотря на то, что мне нравится материализовать, нелегко переопределить многие вещи.

snippet of frontend/style.css” file ↓↓↓↓
#fourth-circle {
width: 200px;
height: 200px;
background: whitesmoke;
                                    border: 3px solid whitesmoke;
                                          text-size-adjust: 15px;
                                            margin: -410px 600px;
                                              margin-top: -500px;
                                            margin-bottom: 200px;
                                              border-radius: 50%;
                                              text-align: center;
}

search.js, где найдены все функции (включая некоторые вызовы выборки), принадлежащие классу Search…

class Search {
static all = []
constructor(country, continent, totalCases, recovered, newCases,
activeCases, newDeaths, totalDeaths, countryPopulation,
totalTests, date) {
this.country = country;
this.continent = continent
this.totalCases = totalCases;
this.recovered = recovered;
this.newCases = newCases;
this.activeCases = activeCases;
this.newDeaths = newDeaths;
this.totalDeaths = totalDeaths;
this.countryPopulation = countryPopulation;
this.totalTests = totalTests;
this.date = date;
}

конструктор - это аргумент, в который передаются сведения о поиске.

this эквивалентно вызову себя…

если this вызывается в статической функции:

static functionName(){
this = the class value
}

если this вызывается внутри функции экземпляра:

functionName() {
this = the instance value
}

аргументы конструктора также передаются в файле strong params .. backend rails API «search_controller.rb»

snippet from the Rails Covid-19-api 
↓↓↓↓
def search_params
params.require(:search).permit(:country, :continent, :totalCases, :recovered, :newCases, :activeCases, :newDeaths, :totalDeaths,
:countryPopulation, :totalTests, :date)
end

затем strong-params передается в метод create файла search_controller.rb

snippet from the Rails Covid-19-api 
↓↓↓↓
def create
@user = User.first
@search = Search.new(search_params)
@user.searches << @search
if @search.save
render json: @search, status: :created
else
render json: @search.errors.full_messages, status: :unprocessable_entity
end
end

который также определен и называется классом поиска.

(я подробнее расскажу об этом поздно)

const strongParams = {
search: {
country: country.country,
continent: country.continent,
countryPopulation: country.population,
totalCases: country.cases.total,
recovered: country.cases.recovered,
newCases: country.cases.new,
activeCases: country.cases.active,
newDeaths: country.deaths.new,
totalDeaths: country.deaths.total,
countryPopulation: country.population,
totalTests: country.tests.total,
date: country.day
}
}

это фрагмент моего POST-запроса к моему backend Ruby rails API ↓↓↓↓

fetch('http://localhost:3000' + '/searches.json', {
method: "post",
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(strongParams)
})
.then(resp => resp.json())
.then(country => {
(country);
})

ps .. вызов выборки может быть вызван либо в файле search.js (класс Search), либо в файле index.js

Вам, наверное, интересно, почему я не вызвал функцию перед данными (страна), которые я не могу объяснить…

чтобы получить информацию о поиске пользователей, я сделал еще один вызов API к внешнему API, который я нашел быстро ..

function myApi4(){
fetch("https://covid-193.p.rapidapi.com/statistics", {
"method": "GET",
"headers": {
"x-rapidapi-host": "covid-193.p.rapidapi.com",
"x-rapidapi-key": "9d691e50d2msh4aa205c2ff027f5p10f338jsn0e4e7c874dc3"
}
})
.then(res => res.json())
.then(value => {
Search.search(value);
})
.catch(err => {
console.log(err);
});
}

внутри вызова API я передал данные (значение) запроса API внутри функции search () .. и поскольку функция поиска находится внутри класса Search, я поставил Search перед ней ..

Search.search(value)

фрагмент функции search (), расположенный в классе Search ↓↓↓↓

static search(value) {
const searchValue = document.getElementById("countryName")
const newValue = searchValue.value.charAt(0).toUpperCase() + searchValue.value.slice(1)
const country = value.response.find(val => val.country === newValue)
if(!country){
alert("Invalid entry")
}
const strongParams = {
search: {
country: country.country,
continent: country.continent,
countryPopulation: country.population,
totalCases: country.cases.total,
recovered: country.cases.recovered,
newCases: country.cases.new,
activeCases: country.cases.active,
newDeaths: country.deaths.new,
totalDeaths: country.deaths.total,
countryPopulation: country.population,
totalTests: country.tests.total,
date: country.day
}
}
const ser = document.getElementById("searchR")

const p = document.createElement("h4")
const p2 = document.createElement("p")
const p3 = document.createElement("p")
const p4 = document.createElement("p")
const p5 = document.createElement("p")
const p6 = document.createElement("p")
const p7 = document.createElement("p")
const p8 = document.createElement("p")
const p9 = document.createElement("p")
const p10 = document.createElement("p")
const p11 = document.createElement("p")

p.innerText = country.country
p2.innerText = country.continent
p9.innerText = 'Population: '
p9.innerText += country.population
p3.innerText = 'Total Cases: '
p3.innerText += country.cases.total
p4.innerText = 'Recovered: '
p4.innerText += country.cases.recovered
p5.innerText = 'New Cases: '
p5.innerText += country.cases.new
p6.innerText = 'Active Cases: '
p6.innerText += country.cases.active
p8.innerText = 'Total Deaths: '
p8.innerText += country.deaths.total
p7.innerText = 'New Deaths: '
p7.innerText += country.deaths.new
p10.innerText = 'Total Tests: '
p10.innerText += country.tests.total
p11.innerText = 'Date:  '
p11.innerText += country.day

ser.appendChild(p)
ser.appendChild(p2)
ser.appendChild(p3)
ser.appendChild(p4)
ser.appendChild(p5)
ser.appendChild(p6)
ser.appendChild(p7)
ser.appendChild(p8)
ser.appendChild(p9)
ser.appendChild(p10)
ser.appendChild(p11)

fetch('http://localhost:3000' + '/searches.json', {
method: "post",
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(strongParams)
})
.then(resp => resp.json())
.then(value => {
(value);
})
resetInputs()  (explained later)
}

как вы можете видеть, я вызываю запрос на выборку внутри функции search (), и поскольку strongParams (, который содержит значение переменной страны) определен внутри функции, в которой находится вызов выборки, было не нужно вызывать функцию….

snippet form "frontend/style.css" 
↓↓↓↓
#first-circle {
width: 500px;
height: 500px;
background: whitesmoke;
/* background: rgba(255,255,255,0.5); */
border: 3px solid whitesmoke;
text-size-adjust: 15px;
margin: auto;
margin-top: 200px;
border-radius: 50%;
text-align: center;
margin-right: 470px;
overflow: auto;
background-image: url(img/earthcov.jpg);
background-size: auto;
background-attachment: auto;
}
snippet from the website of search()
↓↓↓↓

The first line of code in the function
     
const searchValue = document.getElementById("countryName")
is grabbing the input buy the id name and setting the variable searchValue equal to the it.
snippet from frontend/index.html file ↓↓↓↓
 <input type="text" id="countryName" name="country-name" class="input" placeholder="Country Name..">

.

the the second line of code in the function 
const newValue = searchValue.value.charAt(0).toUpperCase() + searchValue.value.slice(1)
is making sure every input is capitalized (so whether you put in china or China it still gives you Chinas covid-19 cases info)
although there is a slight flaw.. 
*if all caps were put in it would throw an error and that is why we have the forth line of code 

← website snippet 
if(!country){ alert("Invalid entry")
}
which reads if the country isn't in the database alert saying "invalid entry"

.

the third line of code in the function 
const country = value.response.find(val => val.country === newValue)
↑↑↑↑
// here were iterating through the value (which is being passed in as an arg in the search(value) and getting the individual country and setting it equal to the value that is being entered inside of out search with the .find() method.
The find() method executes the function once for each element present in the array: If it finds an array element where the function returns a true value, find() returns the value of that array element (and does not check the remaining values) Otherwise it returns undefined.

так что все поиски, которые были сделаны на сайте, передаются в API rails ...

Я сделал еще пару вызовов «GET» к API, который нашел в Интернете для получения дополнительной информации ... и добавил еще две функции allDeaths () && allRecovered (), чтобы разместить их в верхней части страницы вместе с allCases ().

Each of these functions are located inside of the Search class and each have their own API call that they're getting their values from... which is identical to the first myApi() function i posted in the beginning of this blog...
snippet from the website  ↓↓↓↓

snippet from search.js file  ↓↓↓↓
static allDeaths(value){
const val = value.response.reduce((acc, val) => {
return val.deaths.total + acc }, 0)
h32().innerText = val
}

snippet form style.css file ↓↓↓↓
#third-circle {
width: 200px;
                                          height: 200px;
                                             background: whitesmoke;
                                       border: 3px solid whitesmoke;
                                             text-size-adjust: 15px;
                                               margin: -410px 900px;
                                                      margin-top: ;
                                              margin-bottom: 200px;
                                                 border-radius: 50%;
                                                 text-align: center;
                                                                }
snippet from the website  ↓↓↓↓

snippet from search.js   ↓↓↓↓
static allRecovered(value){
const val = value.response.reduce((acc, val) => {
return val.cases.recovered + acc
}, 0)
h33().innerText = val
}
snippet from style.css     ↓↓↓↓
#second-circle {
                                                       width: 200px;
                                                      height: 200px;                  
snippet from index.html                      background: whitesmoke;
↓↓↓↓                                   border: 3px solid whitesmoke;
                                             text-size-adjust: 15px;
<div id="second-circle" >                      margin: -700px 280px;
<h4 id="totalR">Total Recovered<h4>                    margin-top: ;
<h3 id="allRecovered"> </h3>                   margin-bottom: 200px;
</div>                                           border-radius: 50%;
                                                 text-align: center;
                                              background-size: auto;
                                                                }
they're also doing the same exact thing as the allCases() by using 
the reduce() method to sum up all the info.
- allDeaths() summing up all the deaths caused by Covid-19 across the globe
-allRecovered() summing up all the recovered cases form Covid-19 across the globe 

чтобы получить информацию о пользователе, я сделал пару вызовов GET для backend rails API.

* Последние поиски * && * страна с наибольшим количеством просмотров *

snippet from the website
↓↓↓↓
                     *the most viewed country*


snippet from style.css 
↓↓↓
                                         #sixth-circle {
                                           width: 650px;
                                          height: 150px;
                                   background: whitesmoke;
                             border: 3px solid whitesmoke;
                                   text-size-adjust: 15px;
                                           margin: 380px ;
                                       margin-top: -350px;
                                       border-radius: 50%;
                                       text-align: center;
                                      margin-right: 260px;
                                         overflow: scroll;
                                                     }
snippet from index.html 
↓↓↓↓
<div id="sixth-circle" >
<h4 id="userMostViews">Most Views..</h4>
<h3 id="mostViews"> </h3>
</ul>
</div>
snippet from search.js 
↓↓↓↓
static mostVs(data) {
const country = data.map(da => da.country)
let x = 1;
let y = 0;
let mostViewed;
for (let i=0; i<country.length; i++)
{
for (let j=i; j<country.length; j++)
{
if (country[i] == country[j])
y++;
if (x<y)
{
x=y;
mostViewed = country[i];
}
}
y=0;
}
const mostViews = document.getElementById("mostViews")
const p = document.createElement("p")
p.innerText = mostViewed
mostViews.appendChild(p)
} 
}
the last few lines of code are doing exactly what they say.. 
grabs an element my its id name
const mostViews = document.getElementById("mostViews")
creates the element <p></p>
const p = document.createElement("p")
adds the mostViewed variable which is country[i]
into the <p></p> element
p.innerText = mostViewed
adds the <p></p> element and the value inside it into the variable mostViews which is the html with the id of mostViews
<h3 id="mostViews"> </h3>
mostViews.appendChild(p)
mostVs(data) {
the code in the function mostVs(data) looks complicated but it's pretty simple
* it iterates through each element in the array comparing it to see * if the elements are identical 
* it adds one to the x variable 
              and 
* if x is higher than y
* it sets the y variable to the value of x
              and 
* sets the variable mostViewed to the element that is being compared.. 
* the element with the highest repetition wins 
}

.

snippet from the website
↓↓↓↓
                         *Recent Searches*

←
←
snippet from style.css 
↓↓↓
#fifth-circle {
                                           width: 650px;
                                          height: 150px;
                                 background: whitesmoke;
                           border: 3px solid whitesmoke;
                                 text-size-adjust: 15px;
                                         margin: 380px ;
                                      margin-top: 700px;
                                     border-radius: 50%;
                                     text-align: center;
                                    margin-right: 100px;
                                       overflow: scroll;
                                                     }
snippet from index.html 
↓↓↓↓
</div>
<div id="fifth-circle" >
<h4 id="user">Recent Searches..</h4>
<h3 id="userInfo"> </h3></div>
snippet from index.js
↓↓↓↓
static recentSearches(data) {
const userCountry = data.map(da => da.country)
const userInfo = document.getElementById("userInfo")
const p = document.createElement("p")
p.innerText = userCountry
userInfo.appendChild(p)
}
recentSearches(data) {
the block in this function iterates using the map() method and finds all the countries.
sets the method to the variable userCountry and inserts it into the 
<p></p> thats created.. const p = document.createElement("p")
which is set to the variable p 
then adds the variable p to the userInfo variable 
const userInfo = document.getElementById("userInfo")
which is grabbing the html element by its ID name.. 
<h3 id="userInfo"> </h3></div>
it then adds the p variable (which hold the value of userCountry)
to the userInfo variable
userInfo.appendChild(p)

}

ниже находится прослушиватель событий DOMContentLoaded, который загружает все функции в нем, как только загружается DOM.

document.addEventListener("DOMContentLoaded", function(){
onCall()
myApi()
myApi2()
blink()
blink2()
myApi3()
blink3()
getRails()
Search.userInfo()
})

onCall () содержит слушателей событий в своем блоке ... для прослушивания («событие», функция)

snippet from index.js
↓↓↓↓
function onCall() {
btn().addEventListener("click", changeColor)
form().addEventListener("submit", submit)
}
function changeColor() {
btn().style.color = "green"
}
if you're wondering what button is its a global function inside the index.js.. (ill list them all later)
function submit(e) {
e.preventDefault()
myApi4()
}
this function prevents the page from reloading with the event of the "submit" key being pressed with the block
e.preventDefault()
the function myApi4() hold the submit button with in it 

function resetInputs() {
const searchValue = document.getElementById("countryName")
const ser = document.getElementById("searchR")
searchValue.value = ""
}
this function empties the search bar after an input is submitted.
which is being called at the end of the search() function 

это список всех моих глобальных функций ..

const btn = () => document.getElementById('btn')
const totalR = () => document.getElementById('totalR')
const totalD = () => document.getElementById('totalD')
const totalC = () => document.getElementById('totalC')
const h3 = () => document.getElementById('allCases')
const h32 = () => document.getElementById('allDeaths')
const h33 = () => document.getElementById('allRecovered')
const form = () => document.getElementById("find-cases")
const allInputs = () => document.getElementById("all-inputs")
const searchValue = () => document.getElementById("countryName")

Я также добавил функцию blink (), если вы заметили в прослушивателе событий DOMContentLoaded

document.addEventListener("DOMContentLoaded", function(){
onCall()
myApi()
myApi2()
blink()
blink2()
myApi3()
blink3()
getRails()
Search.userInfo()
})

эти функции вызываются в allCases (), allRecovered (), && allDeaths () и действуют в точности так, как их имя заставляет данные мигать

они все идентичны, поэтому укажите только один

function blink() {
const h3 = document.getElementById('allCases');
setInterval(function() {
h3.style.display = (h3.style.display == 'none' ? '' : 'none');
}, 1000);
}
*this function grabs the element my its ID..
* calls the method setInterval()
and sets the 1000 arg at the end that controls the timing of the blink

Спасибо за прочтение :)