Создаем проект
Качай сконвертированный файлик: 470_data.json
Теперь создадай папку под проект и запихай в нее этот сконвертированный файлик, которые содержит отзывы о курсе =)
Не забудь его переименовать в data.json
чтобы получилось как у меня, вот так:

создадим теперь болванку index.html, сразу в нее бутстрап подключим
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap demo</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
</head>
<body>
<h1>Hello, world!</h1>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe" crossorigin="anonymous"></script>
</body>
</html>
Так как мы будем писать много js-кода, чтобы он не мешался, закинем его в отдельный файл.
Создадим файлик main.js. Получится вот так:

теперь подключим main.js к нашему index.html

Проверим что он действительно подключился.
Загоним в main.js какой-нибудь простой код, например:

и запустим liverserver щелкнув на index.html правой кнопкой

если видим что-то такое значит все работает =О

И так, теперь давай пробовать работать с данными.
Чтение содержимого файла
В браузере нет возможности прочитать файл напрямую.
И это даже несмотря на то что наш файлик с данными лежит в папке рядом с нашим index.html,
мы не можем его открыть

но мы можем его скачать =О
Да-да. То есть открыть нельзя, а скачать можно =)
Но качать мы его естественно не руками, а через js. Почему?
А затем, чтобы мы могли как-нибудь манипулировать его данными.
Так как файл в формате json, то javascript автоматом преобразует его в переменную.
Качаем файл
В общем, меньше слов, больше дела. Качаем файл. Пишем в main.js:
// main.js
// создадим функцию обертку под наш код
// тут странное слово async,
// но это короче, чтобы мы могли выполнять асинхронный код
// ну то есть делать запросы и ждать ответа от сервера
async function process() {
// отправляем запрос на скачивание файла /data.json
// наличие слеша перед data.json вообще в данном случае не обязательно
// но считается хорошей практикой
// await означает типа: жди ответа на запроса
let r = await fetch("/data.json");
// когда ответ на запрос придет,
// то его значение положится
// в переменную r
// так как в ответе на запрос помимо самих данных
// есть еще всякая информация, то надо еще
// преобразовать ответ в объект js
// для этого используется r.json()
let data = await r.json();
// после того как этот запросы выполнится
// в data будет содержимое файла в виде словарика
// выведем его в консоль
console.log(data);
}
// запускаем функцию
process();
глянем что происходи в консольке:

это тот самый data
если понажимать на эту штуку, то можно посмотреть содержимое

Проверка через network
Кстати, так как мы делаем запрос. То можно проверить был ли действительно сделан запрос. Для этого можно сходить в консольку во вкладку Network
, выбрать там Fetch/XHR
, перегрузить страницу, и тыкнуть на имя файл
, еще можно на Preview
чтобы увидеть содержимое запроса.
Тут отразятся вся fetch запросы которые делались скриптами на этой странице.

У меня тут еще есть какой-то config.js… но это какое-то расширение, чего-то там делает, так что можно его игнорить.
Работаем с данными
Вернемся к скрипту. Я вот там мильон комментов написал, но по сути он же совсем не страшный и выглядит вот так:
// main.js
async function process() {
let r = await fetch("/data.json");
let data = await r.json();
console.log(data);
}
process();
При работе с данными абсолютно на любому языке программирования надо освоить две главных функции, это filter
и map
. Это так называемые элементы функционального программирования.
Функциональное программирование – это типа про функции, но хитрее. В нем, короче, одни функции передаются в другие функции и там всякие непотребства творятся. В общем ужас-ужас, но народу нравится.
Но чтобы было проще их понять начнем с другой функции, которая называется forEach
Функция forEach
Как можно догадаться по названию, эта функция “что-то должна делать для каждого”.
А вот чего не понятно?
Попробуем вывести один отзыв из нашего файлика,
// main.js
async function process() {
// это не трогам
let r = await fetch("/data.json");
let data = await r.json();
// взял первый отзыв
let item = data[0];
// вывел в консоль
console.log(first);
}
process()
получим такое

попробуем теперь вывести какой-нибудь конкретный ответ в этом отзыве. Например, на предмет полезности курса. Получится вот так:

глянем что выведет:

ну вроде нормально работает)
Допустим я теперь хочу проверить значение по этому ключу, и как-то на него среагировать
async function process() {
let r = await fetch("/data.json");
let data = await r.json();
let item = data[0];
if (item['Насколько материал курса был понятен?'] == "В основном") {
console.log("Говорит что в основном понравился")
}
}
в консольке все корректно.
А теперь допустим я хочу, чтобы он каждый элемент списка проверил поэтому же условию. В принципе я могу написать так:
async function process() {
// ... скачивание не трогаем
let item = data[0];
if (item['Насколько материал курса был понятен?'] == "В основном") {
console.log("Говорит что в основном понравился")
}
item = data[1]; // тут let уже не нужен, так переменную объявляли выше
if (item['Насколько материал курса был понятен?'] == "В основном") {
console.log("Говорит что в основном понравился")
}
item = data[2];
if (item['Насколько материал курса был понятен?'] == "В основном") {
console.log("Говорит что в основном понравился")
}
// ...
// и так пока не кончится, но я хз сколько их там этих значений, вдруг стотыщ =О
}
Но можно же это написать с помощью цикла:
async function process() {
let r = await fetch("/data.json");
let data = await r.json();
for (item of data) {
if (item['Насколько материал курса был понятен?'] == "В основном") {
console.log("Говорит что в основном понравился")
}
}
}
И мы будем правы, оно же работает, и прекрасно.
Что-то такое выведет

Но нам то надо функциональщину, чтобы всякие хитрости с данными делать.
Так что для того чтобы нам жизнь сахаром не казалось, «special for you», как говорится, человечество придумало forEach
.
ForEach – это функция, которой передается другая функцию и вот она эту функцию выполняет по одному разу для каждого элементов массива.
По сути тот же цикл. Но пишется вот так
data.forEach(item => {
if (item['Насколько материал курса был понятен?'] == "В основном") {
console.log("Говорит что в основном понравился")
}
})
если сравнить с методом через цикл:

Вроде похоже.
Но что же тут на самом деле происходит
data.forEach
– это вызов функции forEach у массива data
data.forEach(item => { ... })
– вот это вот item => { ... }
, по сути передача функции в качества параметра функции forEach
item => { ... }
– это так называемся анонимная функция, то есть у нее есть параметр item, есть тело (это как раз то что включается в себя if (item['Насколько материал курса был понятен?'] == "...") ...
- И вот это самый forEach он вызывает эту самую анонимную функцию и в item поочереди передает элементы массива
Эту штуку еще можно было так написать
function processItem(item) {
if (item['Насколько материал курса был понятен?'] == "В основном") {
console.log("Говорит что в основном понравился")
}
}
data.forEach(processItem)
возможно так будет понятнее.
Короче в итоге все должно выглядеть вот так:
// main.js
async function process() {
let r = await fetch("/data.json");
let data = await r.json();
data.forEach(item => {
if (item['Насколько материал курса был понятен?'] == "В основном") {
console.log("Говорит что в основном понравился")
}
})
}
process()
Попробуй теперь сделать задание
Задание
Используя forEach написать код, который используя ответ Оцени работу преподавателя по шкале от 1-10 / 10 – высоко оцениваю работу преподавателя. 1 – совсем не понравилась работа преподавателя
будет выдавать что-то вроде
- от 1 до 8 – преподавателю есть над чем поработать
- больше 8 – препод огонь
Причем написать тремя разными способами
- с использованием цикла
- с использованием анонимной функции
- и с использованием настоящей функции