Node Jokes App

Домашнее задание четвёртой темы курса Geekbrains Node JS.
Необходимо создать веб-интерфейс, который позволяет получать данные из одного из нескольких сайтов (выбор возможен через форму) и указывать количество новостей на страницу.

Устанавливаем модули
- express - фреймворк для быстрого создания приложения
- consolidate - для подключения handlebars - шаблонизатора для создания динамических страниц
- request - для парсинга данных
- cheerio - для фильтрации полученных в ходе парсинга данных

Подключаем модули

const express = require('express');
const consolidate = require('consolidate');
const path = require('path');
const request = require('request');
const cheerio = require('cheerio');
const { promisify } = require('util');


Создаём переменные

Для того чтобы запрос приходил в виде промиса к которому можно применить функцию async/await

const promisifyRequest = promisify(request);

Порт, по которому будет работать приложение

const PORT = process.env.PORT || 80

Создаём приложение

const app = express();

Создаём сервер (его код на странице последний)

app.listen(PORT, () => {
console.log('Server has been started!');
});


Подключаем handlebars

app.engine('hbs', consolidate.handlebars);
app.set('view engine', 'hbs');
app.set('views', path.join(__dirname, '..', 'views'));

Эта строка нужна чтобы получать данные формы

app.use(express.urlencoded({ extended: false }));

Этот код определяет что загружается при открытии страницы

app.get('/', (req, res) => {
  res.render('jokes');
})
;

- res.render можем использовать потому что подключён handlebars
- jokes - файл jokes.hbs в котором разметка страницы

<h2>Jokes</h2>

<form action="/" method="POST">
<input type="number" value=10 name="count" /><br/>
<select name="source">
<option value="bash" selected="selected">Bash.org</option>
<option value="anekdot">Anekdot.ru</option>
</select>
<input type="submit" value="Отправить" />
</form>

{{#if err}}
<h3>{{err}}</h3>
{{/if}}

{{#if jokes}}
<ul>
{{#each jokes}}
<li>{{this}}</li>
{{/each}}
</ul>
{{/if}}

Смена источника и количества выводимых на странице шуток при POST-запросе

app.post('/', async (req, res) => {
  const { count = 10, source = 'bash' } = req.body;
  if (source === 'bash') {
    const { body } = await promisifyRequest('https://bash.im/');
    const $ = cheerio.load(body);
    const quotes = Array.prototype.slice.call(
      $('.quote__body').map((_, element) => $(element).text()), 1, count);
    res.render('jokes', {
      jokes: quotes
    });
  } else if (source === 'anekdot') {
    const { body } = await promisifyRequest('https://www.anekdot.ru/');
    const $ = cheerio.load(body);
    const quotes = Array.prototype.slice.call(
      $('.topicbox .text').map((_, element) => $(element).text()), 1, count);
    res.render('jokes', {
      jokes: quotes,
    });
  } else {
    res.render('jokes', {
      err: 'Такой источник не поддерживается',
    });
  }
});

Результат https://node-jokes-app.herokuapp.com/