Search

Dark theme | Light theme

April 6, 2017

Ratpacked: Conditionally Map Or Flatmap A Promise

When we want to transform a Promise value we can use the map and flatMap methods. There are also variants to this methods that will only transform a value when a given predicate is true: mapIf and flatMapIf. We provide a predicate and function to the methods. If the predicate is true the function is invoked, otherwise the function is not invoked and the promised value is returned as is.

In the following example we have two methods that use the mapIf and flatMapIf methods of the Promise class:

// File: src/main/java/mrhaki/ratpack/NumberService.java
package mrhaki.ratpack;

import ratpack.exec.Promise;

public class NumberService {

    public Promise<Integer> multiplyEven(final Integer value) {
        return Promise.value(value)
                      .mapIf(number -> number % 2 == 0, number -> number * number);
    }
    
    public Promise<Integer> multiplyTens(final Integer value) {
        return Promise.value(value)
                      .flatMapIf(number -> number % 10 == 0, number -> multiplyEven(number));
    }
    
}

Now we take a look at the following specification to see the result of the methods with different input arguments:

// File: src/test/groovy/mrhaki/ratpack/NumberServiceSpec.groovy
package mrhaki.ratpack

import ratpack.test.exec.ExecHarness
import spock.lang.Specification
import spock.lang.Subject

class NumberServiceSpec extends Specification {

    @Subject
    private final numberService = new NumberService()

    void 'even numbers must be transformed with mapIf'() {
        when:
        final result = ExecHarness.yieldSingle {
            numberService.multiplyEven(startValue)
        }

        then:
        result.value == expected

        where:
        startValue || expected
        1          || 1
        2          || 4
        3          || 3
        4          || 16
    }

    void 'ten-th numbers must be transformed with flatMapIf'() {
        when:
        final result = ExecHarness.yieldSingle {
            numberService.multiplyTens(startValue)
        }

        then:
        result.value == expected

        where:
        startValue || expected
        1          || 1
        10         || 100
        2          || 2
        20         || 400
    }
}

Written with Ratpack 1.4.5.