Ожидайте неожиданного с Angular и RxJS

Ожидайте неожиданного с Angular и RxJS

23 ноября 2022 г.

Что привлекает знатоков Angular и расстраивает новичков? То же самое, RxJS.

Почему это так сложно для новичков? Одна из причин в том, что существует немалое количество операторов, которые нужно знать и без поиска понимать разницу между concatMap, switchMap и mergeMap.

Почему он так популярен среди тех, кто его уже изучил? Потому что вы начинаете понимать всю мощь RxJS, когда с помощью пары операторов вы можете сделать то, что вы написали бы в императивном коде за полдня на двух страницах. Ведь так приятно чувствовать себя богом, когда код отскакивает от твоих пальцев, а ты радостно рассказываешь коллегам, какой ты крутой и, главное, просто быстро решаешь задачу.

Все помнят, что множественные подписки — это ужасно, а эффекты работают из крана. Но что чаще всего забывают о RxJS? Исключения! Я различаю два типа.

Неожиданные исключения возникают из-за неправильного кода или невероятного ответа сервера в формате JSON — деление на ноль, неопределенное обращение к нулевому объекту, неправильный анализ JSON. Я могу привести много примеров; это полноценные ошибки, требующие внесения изменений в наш код. Ожидаемые исключения — это ошибки, которые мы можем предвидеть в приложении, а самый простой пример — сбой сервера с данными. Здесь программисты ничего не правят в нашем коде, а обычно мы идем ругаться в другую команду.

Эти типы ошибок, я думаю, должны быть разделены по последствиям - в случае первых красиво падать, в случае вторых уметь с ними работать и показывать нашим пользователям что-то из на котором мы можем сделать красивый скриншот «они виноваты, а не мы».

Давайте создадим простое приложение Angular, которое будет загружать данные пользователя GitHub, а затем (не)красиво, но ожидаемо вылетать при попытке загрузить несуществующее. не определено

Демонстрация StackBlitz

Соответственно код выглядит так:

Это относительно простое приложение, которое дает сбой, когда мы не думаем о загрузке несуществующего пользователя. На самом деле, это будет выглядеть как сломанная кнопка, и все, что на ней основано, тоже упадет. Существует множество попыток решения ошибок методами RxJS, и я предлагаю изучить статью Обработка ошибок RxJs: полное практическое руководство .

В Angular я часто видел решение через определение отдельных полей данных, ошибок и isLoading в модели компонентов.

В нашем случае шаблон растет с каждой веткой.

А в машинописном коде приходится делать все поля необязательными, добавляя головной боли при использовании данных в последующих обращениях к другим службам.

Демонстрация StackBlitz

Почему это (как и другие решения) плохо?

  1. Это ужасно, как в машинописном тексте, так и в HTML.
  2. Он будет заполнен проверками if/else на наличие ошибок, особенно когда данные необходимы для вызова следующих служб. Мы просто забываем о таких ожидаемых ошибках, пока он не упадет, и решаем такие задачи точечно.
  3. Сложно вспомнить все случаи, когда все эти флаги должны быть обновлены или сброшены. isLoading = true не имеет смысла при успешной или неудачной загрузке данных.

Предлагаю изначально считать ошибки полноправными жителями нашего города и никогда не доверять бэкенду, даже если мы счастливые обладатели звания FullStack Developer.

Давайте воспользуемся представлением данных, чтобы показать, что оно может содержать как данные, так и ожидаемую ошибку. Знакомьтесь

В общем случае это тип объединения. Слева - ошибка, справа - правильные данные.

Тем не менее, я предлагаю использовать что-то другое, кроме самописного шрифта, чтобы его было легко воспринимать. Многие берут его из библиотеки fp-ts, но я предлагаю взять более легкий и понятно @sweet-monads/either.

Проще всего преобразовать его с помощью простого оператора RxJS, который автоматически перехватывает сетевые ошибки и преобразует их в структуру ошибок. Для простоты сохраним только текст ошибки — решение состояния прогресса я рассмотрю в следующей статье.

В чем прелесть такого оператора как отдельного блока в приложении — что мы можем применять его точечно, в разных местах приложения, а не мигрировать целиком? Он также отделяет ожидаемые ошибки от неожиданных.

Код, использующий этот оператор, будет выглядеть следующим образом.

Данные лучше отображать в HTML, создавая специальные директивы и компоненты-обертки (это также доступно в альфа-версии в npm как пакет). Я не буду их здесь приводить, а предлагаю изучить обновленный пример, включая код, по адресу эта ссылка.

Основные изменения связаны с появлением компонента Both и использованием правильных данных через структурную директиву ifRight.

Теперь при ожидаемом сбое сети мы будем показывать текст ошибки, а в случае загруженных данных будем работать с ними. Есть еще задачи, которые необходимо охватить, например. состояния загрузки, но я расскажу о них в следующей статье.

Заключение

Мы уверены, что ожидаемая ошибка будет обработана и показана здесь, в первую очередь для проектов, основанных на генераторах кода.

:::информация Также опубликовано здесь.

:::


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE