Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to make Promise without returned value? #37

Closed
alexanderkhitev opened this issue Apr 14, 2018 · 4 comments
Closed

How to make Promise without returned value? #37

alexanderkhitev opened this issue Apr 14, 2018 · 4 comments

Comments

@alexanderkhitev
Copy link

alexanderkhitev commented Apr 14, 2018

Hello! Great framework! Please tell me how to do Promise without a return value? For example, I update the user name in firebase and I expect some value, but only check for an error. I now write Bool as a return value, although in fact I do not need it, how can this be done differently?

I would also like to know what is better to fix in this code for a more productive / readable code using the Promise framework. Thanks.

Sample code

    private func updateName(_ name: String) -> Promise<Bool> {
        let promise = Promise<Bool>(on: .global(qos: .default)) { fulfill, reject in
            guard let userID = UserRealmManager().getUser()?.id else {
                // TODO: - make custom error
                return
            }
            let ref = Database.database().reference().child(UsersPaths.Main.users.rawValue).child(userID)
            let data = [UsersPaths.UserProperties.displayName.rawValue : userID]
            ref.updateChildValues(data, withCompletionBlock: { (error, _) in
                if let error = error {
                    reject(error)
                } else {
                    fulfill(true)
                }
            })
        }
        return promise
    }

@shoumikhin
Copy link
Contributor

shoumikhin commented Apr 15, 2018

Hi Alex,

I imagine wrap could work for you?

private func updateName(_ name: String) -> Promise<Type> {
  return wrap(on: .global(qos: .default)) { handler in
    guard let userID = UserRealmManager().getUser()?.id else { throw CustomError }
    let ref = Database.database().reference().child(UsersPaths.Main.users.rawValue).child(userID)
    ref.updateChildValues([UsersPaths.UserProperties.displayName.rawValue : userID], handler)
  }
}

Where the Type of the promise would be the same as whatever the type of updateChildValues completion handler is. You may also need to specify the type of handler for wrap operator explicitly as (handler: @escaping (Type?, Error?) -> Void) to disambiguate between other wrap overloads.

If you'd like to use Void instead of that Type, you can chain another then at the end, like so:

return wrap { handler in
  //...
}.then { _ in () }

Where () constructs and returns an empty tuple, i.e. the value of type Void.

@alexanderkhitev
Copy link
Author

alexanderkhitev commented Apr 15, 2018

Hi @shoumikhin

Thank you very much for your detailed answer.

I make all network logic in the background thread.

@richardtop
Copy link

Hi @alexanderkhitev and @shoumikhin, I use Void type for such cases:

Promise<Void> - it works great for cases, when you only need to check for the result:

  @discardableResult func logOut() -> Promise<Void> {
// Clear local storage
    return client.request(EXPIRE_TOKEN_API_ENDPOINT)
  }


// Somewhere in code

loginService.logOut()

or:
loginService.logOut().then .....

@shoumikhin
Copy link
Contributor

Hi @alexanderkhitev,

I've updated the answer above. Since 1.1.0 you can pass an arbitrary dispatch queue to the wrap operator (former resolve) to achieve the behavior you wanted. Let us know if still have any issues, we're happy to help.

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants