Group Group Group Group Group Group Group Group Group

Chapter 4: Chaining Futures

At the section “Chaining futures” I can see this example code here:

Is that first block of code (marked line) correct? Why is it flatmapped to HTTPStatus.self? Shouldn’t it be User.self or rather [User].self? In the next block it IS flatmapped to User.self.

I find it a bit confusing.

Hi @pintiboy! So yes, futures are confusing, but it does eventually make sense. The highlighted line is correct as written. The reason is that the closure for that flatMap will return Future<HTTPStatus>. That happens because the map inside the flatMap returns Future<HTTPStatus> because the closure for that one returns HTTPStatus (remember if it’s a map, you return a non-future inside the closure and that gets turned into a future. If it’s flatMap you return a future inside the closure and that’s the return type).

When chaining, things are slightly different. In the chaining example, the flatMap returns Future<User> because you’re returning the result of the save, which is the future user. The Future<User> is then passed into the map which returns HTTPStatus. Because they’re chained, the last result of the chain is the eventual return type for that block, again Future<HTTPStatus>. Does that make sense?

There is a really fitting emoji for this: :exploding_head:
Thanks for the explanation, I guess I have to read that a thousand times more :smiley:

My first thought now is: Chaining makes more sense and is probably easier to understand :wink:

Weird I find nesting easier as it’s all the same return type! :sweat_smile:

But whatever works for you! Once it clicks it makes life a lot easier. Chaining definitely helps make the code a bit more readable since you don’t end up nesting several layers deep. However, one word of caution - sometimes you have to nest if you need the result of a previous future.

Ok, now another thing. I still have problems with that “to:”-Part of these flatMap functions. What’s the point of that? Why is it important? I mean, let me pick one random handler, let’s say the getUserHandler of page 115:

Why is it important that it says […] flatMap(to: User.self) […] When I omit the “(to: User.self)” part everything works still fine. So why should I write that long version?

The to: overload is from the 4.1 days where the compiler would have problems inferring the return type. If you provided it, you got much better error messages, but those have improved over the last year or two. So feel free to leave it off! (It’s no longer an option in Vapor 4 either)

Thanks for the Answer, Tim. Very appreciated. Now everything gets a little clearer for me. And with 4.1 you mean Swift 4.1, right?

Yeah sorry, 4.1 refers to Swift 4.1