@dmitriu256

Как подгрузить новости из БД по нажатию кнопки?

Как подгружать новости из БД MySql по клику на кнопку?
Использую связку JS + NodeJs(Express) + MySql

Моя реализация
1) Изначально на страницу загружаю 3 новости из бд (AJAX запрос) с указанием LIMIT
2) Далее по нажатию на кнопку выполняется два запроса
- определяем количество записей в таблице (использую COUNT в mysql)
- зная начальные LIMIT (from, to) переопределяю эти значения.

Как хочу контролировать количество выводимых статей (через задание LIMIT)
1) Изначально при загрузке трех новостей LIMIT 0(from), 3(lim)
2) При нажатии на кнопку лимит меняем в след порядке LIMIT 3(где from = lim из пункта1 ), 1 (показывать только одну запись)
3) При следующем нажатии кнопки LIMIT 4,1
4) Далее LIMIT 5,1 и тд, пока from не будет равен COUNT из предыдущего запроса
5) Скрыть кнопку. (статей в базе больше нет).

Код пункт 1 (загрузка из Бд )
Серверная часть
app.get('/news/:from/:lim', (req,res) => {
    connection.query(`SELECT  * FROM news LIMIT ${req.params.from}, ${req.params.lim}`, function(error, rows) {
        if(error) throw new  Error(error);
        res.json(rows);
    });
});


Клиентская часть
let newsSection = document.querySelector('.news');
    let newsContainer = newsSection.querySelector('.container');

    //Создаем кнопку Все новости
    let newsBtn = document.createElement('button');
    newsBtn.classList.add('button', 'button-o', 'news-button');
    newsBtn.innerText = 'Все новости';

    let lim = 3;
    let from = 0;

    //Ряд
    let newsRow = document.createElement('div');
    newsRow.classList.add('row');

    //AJAX запрос на получения всех новостей из БД

    let newsXhr = new XMLHttpRequest();
    newsXhr.open('GET', `http://localhost:3010/news/${from}/${lim}`);

    newsXhr.setRequestHeader('Content-type', 'application/json; charset = utf-8');

    newsXhr.send();

    newsXhr.addEventListener('readystatechange', function () {
        if (newsXhr.readyState < 4) {

        } else if (newsXhr.readyState === 4 && newsXhr.status === 200) {
            let data = JSON.parse(newsXhr.response);
            console.log(data);

            for(let i = 0; i < data.length; i++) {
                newsRow.append(createNews(data[i]));
            }

        } else {
            console.log('Ошибка');
        }
    });


    if(newsSection.contains(newsContainer)) {
        //Вставка кнопки и ряда с новостями
        newsContainer.append(newsBtn);
        newsBtn.before(newsRow);

    }else{
        console.log(false);
    }


Результат
5ea1c1a6adaff773892997.png

Код нажатие на кнопку Все Новости

Серверная часть (получение количества записей в таблице)
app.get('/news', (req,res) => {
    connection.query(`SELECT COUNT(*) FROM news `, function(error, rows) {
        if(error) throw new  Error(error);
        res.json(rows);
    });
});


Клиентская часть обработки кнопки

newsBtn.addEventListener('click', function () {


        //1 Запрос Количество записей в таблице Новости
        let xhr = new XMLHttpRequest();
        xhr.open('GET', `http://localhost:3010/news`);

        xhr.setRequestHeader('Content-type', 'application/json; charset = utf-8');

        xhr.send();

        xhr.addEventListener('readystatechange', function () {
            if (xhr.readyState < 4) {

            } else if (xhr.readyState === 4 && xhr.status === 200) {
                let tmp = JSON.parse(xhr.response);
                let newsLength;
                for(let key in tmp[0]) {
                    newsLength = tmp[0][key];
                }

                //console.log(newsLength);


                //2 Запрос Выборка новостей из БД
                //Ограничения
                //КАК ПРАВИЛЬНО ЗАДАТЬ УСЛОВИЯ ДЛЯ ЛИМИТОВ
               ******************************************
               from = ++lim;
                console.log(from);

                if (from <= newsLength) {
                    lim = 1;
                    from += lim;

                    console.log(from);
                    //console.log(lim);
*************************************************************************************
                    let newsXhr = new XMLHttpRequest();
                    newsXhr.open('GET', `http://localhost:3010/news/${from}/${lim}`);

                    newsXhr.setRequestHeader('Content-type', 'application/json; charset = utf-8');

                    newsXhr.send();

                    newsXhr.addEventListener('readystatechange', function () {
                        if (newsXhr.readyState < 4) {

                        } else if (newsXhr.readyState === 4 && newsXhr.status === 200) {
                            let data = JSON.parse(newsXhr.response);
                            //console.log(data);

                            for (let i = 0; i < data.length; i++) {
                                newsRow.append(createNews(data[i]));
                            }

                        } else {
                            console.log('Ошибка');
                        }

                    });
                    //Конец запроса 2 на выборку новостей
                }else{
                    console.log(from);
                    //Скрываем кнопку 'Все Новости'
                    newsBtn.hidden = true;
                }

            } else {
                console.log('Ошибка');
            }
            //Конец запроса 1 на получения количество записей в таблице
        });

    });


Результат
5ea1c3fb71cb5976120197.png
Сейчас постоянно выводится последняя запись при нажатии на кнопку. Как правильно настроить диапазон выборки?
Как правильно реализовывать такой вид задачи - вывод остальных статей по клику?
  • Вопрос задан
  • 526 просмотров
Пригласить эксперта
Ответы на вопрос 2
@Kerberosso
А зачем вам делать дополнительный запрос на бэк для получения общего количества новостей и держать информацию о from и lim на клиенте? Пусть бэк при каждом возврате новостей отдаёт общее количество новостей, оставшееся количество новостей и текущий порядковый номер новости. И Вы, исходя из этой информации, будете строить следующий запрос и обновлять UI. Сделать всё это разом на бэке и отдать на клиент проще, чем слать лишние запросы по сети.
Ответ написан
Комментировать
yurakostin
@yurakostin
Front-end developer
Круто, что вы ставите перед собой и решаете задачи. Как я понял, ваше решение работает, и это отлично.

Теперь поставьте перед собой две цели:
  • Сделать ваш код лучше. Например, использовать фреймворк, или пару библиотек, или хотя бы fetch, чтобы не писать столько лютого кода. Разбейте ваш код на части, абстрагируйте его. Уйдите от императивщины в сторону ООП, или ФП
  • Сами подумайте над тем как сделать лучше. Не существует единственно правильного решения задач. Особенного в js =). Всё, что вы сделали другой, более опытный разработчик сделает немного иначе, но и только. В идеале вам нужно пройти этот путь. Например, как написали выше, уменьшить количество запросов. Если у вас есть дома доска, встаньте рядом с ней(ну или воспользуйтесь старой доброй тетрадью), возьмите мел или маркер, и нарисуйте данные, которые вы получаете. Их можно как-то скомпоновать? Можно ли вообще иначе подойти к решению? Как сделать его оптимальнее, уменьшив количество запросов? Как унифицировать решение? Вероятно вы пройдёте долгий путь, но ваша экспертиза возрастёт.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы