When you want to build your logic with small, composable functions you need a functional way to handle conditional logic. You could wrap ternary expressions and if/else statements in functions, handling all of the concerns around data mutation yourself, or you could leverage the conditional functions supplied by Ramda. In this lesson, we'll cover several of Ramda's conditional functions:
In this file, I've acquired Ramda and created an array of product objects. I've also set up a lens and an applied discount function, and I can use that to apply a 50 percent discount to each product by mapping over my adjust price function. If I run this code, we'll see that a 50 percent discount has been applied to the price on each product.
Let's say I want to apply a discount to every one of my products, but I want to apply a different discount based on the product's category. To do that, I've going to reassign adjust price to Ramda's if else function.
If else takes three arguments. The first argument is a predicate function. The second argument is the function to run on the object if the predicate evaluates to true. The third is the function to run if the predicate evaluates to false.
We'll start with the predicate function. For this example, I want to apply a 50 percent discount to anything with category clothes, and a 10 percent discount to everything else. I'm going to use Ramda's prop equals function.
I'm going to say if the prop category equals the value clothes, then I'll return true. If that's true, I want to apply my 50 percent discount. If it's false, I want to make that discount 10 percent. If I run this now, we'll see that the jeans price has been reduced to $40 which is 50 percent of the original price, and everything else has been reduced by 10 percent.
What if I wanted to apply my discount to clothes and not discount any other products? I could come back into the code, and I could handle this a couple different ways. First way would be to apply a zero percent discount. The problem here is that this is still going to run my lens and my apply discount function over the object to essentially do nothing.
The other way I can handle this is to replace this call to over with a call to Ramda's identity function. All identity is going to do is take whatever value is passed into it and return it. Now, if I run this we'll see that the 50 percent discount is still applied to the jeans, and everything else is left at its original price.
There's a more succinct way to write what I just did. I can come over here, and I can remove this identity function. I can replace if else with a call to Ramda's when function. This basically says when the predicate's true, run this function. Otherwise, pass things through as is. If I run this, we'll see the same results where the jeans are discounted and nothing else is.
When has a counterpart called unless that'll do the opposite. This basically says unless the predicate if true, apply a 50 percent discount. I'm going to get a 50 percent discount on everything except for the jeans. When I run this, we'll see that the jeans come back full price and everything else has had that 50 percent discount applied.
Let's say I want to apply a 50 percent discount to clothes, a 10 percent discount to electronics, and leave everything else as is. For cases like this, I'm going to use Ramda's cond function. I'm going to replace unless here with a call to cond.
Cond is going to take an array of arrays as its first argument. I'll select everything inside of my parenthesis, and I'll wrap that in square brackets. That's my outer array. Then each element in this outer array is going to be an array that consists of a predicate function and the function to apply in the case of that predicate evaluates to true. I'm going to wrap this in square brackets as well.
My first argument for this is a pair that says if the category is close, apply a 50 percent discount. I said my second condition was going to be for electronics. I want to apply a 10 percent discount. I can do that my duplicating that array, applying a 10 percent discount, and changing the category check to look for electronics.
Let's take a look at what we have so far. If I run this code, you'll see that I get back jeans with the 50 percent discount applied, the iPhone with the 10 percent discount applied, and I get back two undefined values. Those are my other two products. Because I don't have a case that accounts for those, I just get undefined back in their place. Let's fix that.
In order to account for anything that isn't caught by my first two predicates, I'm going to add one more array. I need a predicate here that's basically going to catch anything that falls through. Ramda supplies a T function which is essentially a function that does nothing but return true. All I want to do for that is use Ramda's identity function to take whatever is passed in here and pass it back untouched.
Now I can run that updated code. We'll see that my discounts are applied to jeans and the iPhone but not to cards and the book.
It's important to note that the cond function is not limited to two or three conditions. I can come in here, and I can have as many of these as I want. Let's say I want to apply 100 percent discount to books, because learning is important.
Now when I run this, I'll get back a book with the price zero. My other discounts have been applied. Anything in the games category has been left untouched.