11

I am finding extremely hard to use PromiseKit 6.13.1 in an apparently simple situation. I have the following two functions returning a Promise<String> but I cannot seem to find a way to use them with ```firstly{}.then{} syntax:

 func promiseGetJWTToken() -> Promise<String> {
    return Promise<String> { seal in
        let error: Error = NSError(domain: "", code: 2000)
        getJWTToken { tokenJWT in
            guard let tokenJWT = tokenJWT else {
                seal.resolve(.rejected(error))
                return
            }
            seal.resolve(.fulfilled(tokenJWT))
        }
    }
}

func promiseGetBEToken() -> Promise<String> {
    return Promise<String> { seal in
        let error: Error = NSError(domain: "", code: 2000)
        getBEToken { result in
            switch result {
            case .success(let response):
                guard let tokenBE = response.token else {
                    seal.resolve(.rejected(error))
                    return
                }
                seal.fulfill(tokenBE)
            case .failure(let error):
                debugPrint(error)
                seal.resolve(.rejected(error))
            case .none:
                seal.resolve(.rejected(error))
            }
        }
    }
}

When I try to use the following as follows

firstly {
   promiseGetJWTToken()
 }.then { tokenJWT in
   // no need go on because I have issues already here         
 }

I receive:

Type '()' cannot conform to 'Thenable'; only struct/enum/class types can conform to protocols

I have also tried, which comes from autocompletion:

promiseGetJWTToken().then { token -> Thenable in
    // no need go on because I have issues already here  
}

In this case I receive:

Protocol 'Thenable' can only be used as a generic constraint because it has Self or associated type requirements

I decided to give PromiseKit a try because I have three network calls dependent on each other on cascade, but I wouldn't expect this to be so hard. Can anyone show me what am I doing wrong?

Fabrizio Prosperi
  • 1,398
  • 4
  • 18
  • 32

3 Answers3

14

The error message is misleading; the real issue is that the .then closure should return a new Thenable. In your examples, the .then closures are empty.

Or just use .done, if not chaining promises.

pipacs
  • 1,049
  • 11
  • 25
  • Excellent answer! PromiseKit is so promise breaking )) – rommex Jul 25 '22 at 11:41
  • I really like using the PromiseKit, but seriously, these error messages make them so hard to figure out what is really going on. Thank you `pipacs`, @v2panda, `user2759839` you all deserved a big upvote! – choofie Feb 01 '23 at 11:07
  • Thank you, I've been losing my mind over this, "I KNOW THAT I HAVE OTHER PROMISES THAT LOOK JUST LIKE THIS" - meanwhile I'm not fulfilling the promise that I made that I'm going to return one from the .then - Thank you again! – Travis Jun 12 '23 at 15:35
11

They replaced that usage of then { } with done { }.

firstly {
   promiseGetJWTToken()
 }.done { tokenJWT in
   // use your token
 }
user2759839
  • 305
  • 1
  • 3
  • 11
3

You can try

 firstly {
   promiseGetJWTToken()
 }.then { tokenJWT -> Promise<String> in
   return promiseGetBEToken()
 }

or

 firstly {
   promiseGetJWTToken()
 }.then { tokenJWT -> Promise<String> in
   promiseGetBEToken() 
   return Promise.value(tokenJWT)
 }
v2panda
  • 51
  • 5