Тестовое задание на Angular. Работа с данными из State.

Aleksandr Serenko
F.A.F.N.U.R
Published in
3 min readJul 5, 2021

В данной статье поговорим об использовании данных из State и рассмотрим нюансы с созданием сервисов, использующих фасады.

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

После того, как появился RoomState можно попробовать вывести список комнат. Но есть один нюанс. Так как в state в начале принимает значение initialState, в котором у нас rooms равны null, то это может вызвать определенные side-effect’ы.

Поэтому чаще всего, создается сервис, который оборачивает работу RoomFacade, следующим образом:

То есть, вместо прямого обращения к rooms$, сначала делается проверка на наличие данных. Другими словами, Angular отреагирует на получения данных только в том случае, когда rooms будет не null.

Но тут есть одна очень страшная ловушка, которая нечевидна.

Допустим, необходимо создать сервис, который будет объединять данные из нескольких state’ов. Например, нужно вывести все отели, и для каждого отеля вывести первый номер, который есть в данном отеле. С точки реализации мы имеем:

  • RoomFacade —фасад, который предоставляет доступ к номерам;
  • RoomService — сервис, который фильтрует данные из state;
  • BuildingFacade — фасад, предоставляющий доступ к отелям;
  • BuildingService — сервис, который использует BuildingFacade и фильтрует данные, предоставляя доступ к отелям.

Нужно создать сервис — BookingService, где можно будет получить объединенные вместе отели и номера.

Вопрос в следующем, что использовать в качестве зависимостей? Пару BuildingFacade и RoomFacade или BuildomgService и RoomService?

Правильным решением является использование первой пары: BuildingFacade и RoomFacade. Это все связано со слоями абстракций (инфраструктурными слоями). Условно создавая новый сервис на второй паре, мы явно получаем зависимость от 2 сервисов: RoomService, который в свою очередь зависит от RoomFacade.

Другими словами можно выразить данное правило в виде — Фасад используется в “final” классе или по крайней мере, в сервисе не должно быть дублирующих свойств.

Например, в RoomFacade есть метод clear. Если некий сервис или компонент использует RoomService, где нужно вызвать метод clear из RoomFacade, что нужно сделать?

Плохой вариант — создать в RoomService метод clear, который вызовет RoomFacade.clear().

И здесь плохой вариант плох тем, что помимо того, что появляется дублирование логики, так и еще появляются толстые связи. Например, в дальнейшем метод clear будет удален из Facade, что делать с данным методом в Service?

Хороший вариант — не использовать RoomService, а сразу использовать RoomFacade и ничего не создавать. Единственное, придется продублировать логику с обращением к данным, но это часто просто один оператор filter.

Резюмируя вышесказанное:

  • При работе с данными, старайтесь использовать Facade и не создавать дополнительных сервисов
  • Если же все-таки явно нужен сервис, то никогда не используйте сервис в других сервисах для получения данных из Facade.
  • Если в компоненте или сервисе потребовалось вызвать данные из Facade, но в данном компоненте или сервисе используется не Facade, а обертка над ним, то необходимо отказаться от обертки и использовать Facade.

Ссылки

Вернуться к оглавлению — Введение.

Следующая статья — Создание lazy страницы.

Предыдущая статья — Использование Ngrx State.

Все исходники на github/fafnur/barinb.

Группа в Medium: https://medium.com/fafnur
Группа в Vkontakte: https://vk.com/fafnur
Группа в Facebook: https://www.facebook.com/groups/fafnur/
Telegram канал: https://t.me/f_a_f_n_u_r
Twitter: https://twitter.com/Fafnur1
LinkedIn: https://www.linkedin.com/in/fafnur

--

--

Aleksandr Serenko
F.A.F.N.U.R

Senior Front-end Developer, Angular evangelist, Nx apologist, NodeJS warlock