0

I'm using PromiseKit in my project and I need to do batch/multiple calls to the API and wait for all responses. Any ideas how to do this? I'm pretty new to PromiseKit, and didn't find anything regarding this on their Github (probably didn't see or understand it)

What I'm trying at the moment and failing is:

    let ids = [1, 2, 3, 4, 5]
    firstly {

               getURLPathsFor(ids) // maybe I'm doing this wrong - this returns a Promise<[String]>

            }.thenMap { url in

                ApiManager.shared.request(url, method: .delete)

            }.done { _ in
                seal.fulfill(())
            }.catch { error in
                seal.reject(error)
            }

    func getURLPathsFor(_ ids: [UInt]) -> Promise<[String]> {
        let path = "/somePath"
        var URLs = [String]()
        return Promise { seal in
            ids.forEach { uid in
                AppConfigManager.shared.getApiUrl(path: path, uid).done { url in
                    URLs.append(url)
                    seal.fulfill(URLs)
                }.catch { error in
                    seal.reject(error)
                }
            }
        }
    }

Any help would be great, really stuck with this one.

Mihai Fischer
  • 329
  • 2
  • 11

1 Answers1

0

So I managed to achieve the batch calls I wanted using PromiseKit and handling all errors together:

private func batchDeleteItem(with itemId: UInt) -> Promise<(UInt, AppError?)> {
    return Promise { seal in
        firstly {
            AppConfigManager.shared.getApiUrl(path: Constants.Api.deleteItemRequestPath, itemId)
        }.then { url in
            ApiManager.shared.request(url, method: .delete)
        }.done { _ in
            seal.fulfill((itemId, nil))
        }.catch { error in
            guard let appError = error as? AppError else {
                seal.reject(error)
                return
            }
            seal.fulfill((itemId, appError))
        }
    }
}

I call this method in a map, and in order to collect the ids of items that couldn't be deleted, I treat the catch with fulfill as wel - rejecting only server side error (this is what I needed for my case) :

return Promise { seal in

        let promises = ids.map { itemId in
            batchDeleteNode(with: itemId)
        }

        when(fulfilled: promises).done { results in
            seal.fulfill(results)
        }.catch { error in
            seal.reject(error)

        }
    }

And to have all the errors grouped and waited for I use when(fulfilled: promises).done {...}

I'm not saying it's perfect but seems to work very well, and I learned a lot in the process regarding PromiseKit.

Mihai Fischer
  • 329
  • 2
  • 11