
В этом видео мы с вами разберем, как удобнее писать условия if else с помощью Ramda.
Представим себе, что нам нужно написать функцию, которая принимает на вход объект (в нашем случае это будет видео), проверяет поле HD внутри объекта и возвращает необходимое нам поле.
const getVideoFilepath = video =>
video.isHD ? video['720p'] : video['480p']
const video = {
'720p': 'funny-video-hd.mp4',
'480p': 'funny-video-480p.mp4',
isHD: true
}
console.log(getVideoFilepath(video))
Если мы посмотрим в браузер, то у нас вывелось funny-video-hd.mp4.
Теперь, нам еще необходимо добавить basepath к ссылке.
const getVideoFilepath = video => {
const file = video.isHD ? video['720p'] : video['480p']
return `/api/videos/${file}`
}
const video = {
'720p': 'funny-video-hd.mp4',
'480p': 'funny-video-480p.mp4',
isHD: true
}
console.log(getVideoFilepath(video))
Все работает как нужно. Что в этом коде плохо? Запись video дублируется несколько раз и нам нужно создавать дополнительную переменную для читабельности.
Давайте попробуем написать тоже самое на Ramda, используя R.ifElse. Первым аргументом оно принимает функцию - условие, которое должно вернуть да/нет, вторым - функцию, которая выполнится если все хорошо, а третьим - функцию, если условие не выполнится.
const getVideoFilepath = R.ifElse(
R.propEq('isHD', true),
R.prop('720p'),
R.prop('480p')
)
Если мы посмотрим в браузер, то нам выводится правильное название. Главная идея в том, что в каждую функцию прокидывается объект, на который вызывается ifElse. Это дает возможность делать сразу то, что нужно с этим обьектом.
В данном случае, мы проверили поле объекта на true, с помощью propEq, а потом выбрали поле с помощью R.prop. Код не содержит повторений и выглядит намного лаконичнее.
Как же нам добавить api в начало названия? Мы можем легко сделать это с помощью R.compose.
const getVideoFilepath = R.compose(
R.concat('/api/videos/'),
R.ifElse(
R.propEq('isHD', true),
R.prop('720p'),
R.prop('480p')
)
)
Как мы видим, код работает как и раньше, но его намного легче считывать и исправлять.
Хочу сразу заметить, что не нужно любую функцию писать на R.ifElse.
Если у нас есть три переменных, то писать R.ifElse для них не имеет особого смысла.
Например, у нас две строки и булевая переменная.
const getMessage = isWorkingTime => {
const onlineMessage = 'We are online'
const offlineMessage = 'We are offline'
return isWorkingTime ? onlineMessage : offlineMessage
}
Эта функция возвращает разные строки в зависимости от того, isWorkingTime true или false.
Если мы попытаемся переписать этот код на R.ifElse, то не выйдет ничего хорошего
const getMessage = isWorkingTime => {
const onlineMessage = 'We are online'
const offlineMessage = 'We are offline'
return R.ifElse(
R.always(isWorkingTime),
R.always(onlineMessage),
R.always(offlineMessage)
)()
}
Так как каждым аргументом ifElse принимает функцию, то нам нужно обернуть наши переменные в R.always, которые каждую из них превращают в функцию, которая возвращает эту переменную.
Поэтому ifElse лучше всего подходит для манипуляций с обьектом, на который он вызывается, а не для замены тернарных операторов.
Если у вас возникли какие-то вопросы или комментарии, пишите их прямо под этим видео.