Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning void in PromiseKit 6

This is what I had working with PromiseKit 4.5

api.getUserFirstName().then { name -> Void in
  print(name)
}

getUserFirstName() returns a Promsise<String>. I updated to PromiseKit 6 and this now throws an error: Cannot convert value of type '(_) -> Void' to expected argument type '(_) -> _'

This error message makes little sense to me. How do I fix this?

EDIT: So this seems to fix it, but I have little understanding as to what's happening with this:

api.getUserFirstName().compactMap { name in
  print(name)
}

What's the difference now between then() and compactMap()?

like image 611
7ball Avatar asked Mar 07 '18 08:03

7ball


1 Answers

In according with PromiseKit 6.0 Guide then was split into then, done and map

  • then is fed the previous promise value and requires you return a promise.
  • doneis fed the previous promise value and returns a Void promise (which is 80% of chain usage)
  • map is fed the previous promise value and requires you return a non-promise, ie. a value.

Why that was happend? As said developers:

With PromiseKit our then did multiple things, and we relied on Swift to infer the correct then from context. However with multiple line thens it would fail to do this, and instead of telling you that the situation was ambiguous it would invent some other error. Often the dreaded cannot convert T to AnyPromise. We have a troubleshooting guide to combat this but I believe in tools that just work, and when you spend 4 years waiting for Swift to fix the issue and Swift doesn’t fix the issue, what do you do? We chose to find a solution at the higher level.

So probably in your case needs to use done

func stackOverflowExample() {
    self.getUserFirstName().done { name -> Void in
        print(name)
    }
}

func getUserFirstName() -> Promise<String> {
    return .value("My User")
}

compactMap lets you get error transmission when nil is returned.

firstly {
    URLSession.shared.dataTask(.promise, with: url)
}.compactMap {
    try JSONDecoder().decode(Foo.self, with: $0.data)
}.done {
    //…
}.catch {
    // though probably you should return without the `catch`
}

See more info at release guide

compactMap was renamed to flatMap see discussions here

like image 81
Ihar Katkavets Avatar answered Oct 14 '22 12:10

Ihar Katkavets