Optionals, flatMap and you
Say we have a UILabel
where we want to display a birthdate with a full format, and an API from where we get a String?
with iso8601
format. One of the ways to do this would be:
let dateFromAPI: String?
// [...]
let dateFormatter = DateFormatter.shared // 1
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
if let dateString = dateFromAPI, // 2
let date = dateFormatter.date(from: dateString) { // 3
dateFormatter.dateFormat = nil
dateFormatter.dateStyle = .full
dateLabel.text = dateFormatter.string(from: date) // 4
}
DateFormatter
s are expensive to create, so we either create it here once, or use a shared one (1), we then check to see if we have a date from our API (2), then check if we can transform it to a date (3), then finally we can assign it to our dateLabel.text (4)
.
What about flatMap
?
let dateFromAPI: String?
// [...]
let dateFormatter = DateFormatter.shared
dateLabel.text = dateFromAPI
.flatMap { // 1
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
return dateFormatter.date(from: $0) // 2
}
.flatMap { // 3
dateFormatter.dateFormat = nil
dateFormatter.dateStyle = .full
return dateFormatter.string(from: $0) // 4
}
If dateFromAPI
is not nil
, the first flatMap
closure will be called (1), where we transform the String
to a Date
(2), which if it’s not nil
(3), the second flatMap
closure is called, where we transform the date intro a String
(4), which will be assigned to dateLabel.text
.
I’m a bit torn on which one is more readable, but other in other scenarios, using the latter might be preferable.
Originally published at https://rolandleth.com.