Reputation: 2537
I'm calling three services in a row. When I'm calling third service, I need to use variable from first service response which is userModel
. I can get second service response from which is initModel
but can't reach first model userModel
. My Question is that how can I use userModel in done block by returning it then blocks?
P.S: I tried to return -> Promise<(UserModel,InstallationModel)>
in first call but because UserModel
is already an object not a promise, I need to convert it to promise to return it. This looks like me a bad way to do it.
As you can see I'm storing it with self.userModel = userModel
which I don't wanna do.
func callService(completionHandler: @escaping (Result<UserModel>) -> Void) {
SandboxService.createsandboxUser().then { userModel -> Promise<InstallationModel> in
self.userModel = userModel
return SandboxService.initializeClient(publicKey: self.keyPairs.publicKey)
}.then { initModel -> Promise<DeviceServerResponseModel> in
self.initModel = initModel
if let unwrappedUserModel = self.userModel {
return SandboxService.deviceServerServiceCaller(authKey: initModel.token.token,apiKey:unwrappedUserModel.apiKey,privaKey: self.keyPairs.privateKey)
}
throw ServiceError.handleParseError()
}.then { serverResponseModel -> Promise<UserModel> in
if let unwrappedInitModel = self.initModel, let unwrappedUserModel = self.userModel {
return SandboxService.sessionServiceCaller(authKey: unwrappedInitModel.token.token, apiKey: unwrappedUserModel.apiKey, privaKey: self.keyPairs.privateKey)
}
throw ServiceError.handleParseError()
}.done { userModel in
completionHandler(Result.success(userModel))
}.catch { error in
completionHandler(Result.error(error))
}
}
Upvotes: 3
Views: 1288
Reputation: 2537
I had also opened issue at PromiseKit page @Github. I'm sharing answer of Mxcl from Github to here also.
func callService(completionHandler: @escaping (Result<UserModel>) -> Void) {
SandboxService.createsandboxUser().then { userModel in
firstly {
SandboxService.initializeClient(publicKey: self.keyPairs.publicKey)
}.then { initModel in
SandboxService.deviceServerServiceCaller(authKey: initModel.token.token, apiKey: userModel.apiKey,privaKey: self.keyPairs.privateKey).map{ ($0, initiModel) }
}.then { serverResponseModel, initModel in
SandboxService.sessionServiceCaller(authKey: initModel.token.token, apiKey: userModel.apiKey, privaKey: self.keyPairs.privateKey)
}
}.pipe(to: completionHandler)
}
Upvotes: 4
Reputation: 2666
I'm not familiar with PromiseKit
but since it is a framework, you cannot really edit the methods in a way that you could include userModel
in callback of .done
method. So what I would do is, have an optional value declared in the class where this code block is executed with the type of userModel, and then set it to received value from first call, then set it back to nil after using it in second one. Like following:
Lets assume type of userModel is UserModel.
final class SampleFetcher {
let userModel: UserModel?
func fetch() {
SandboxService.createsandboxUser().then { userModel in
SandboxService.initializeClient()
// save userModel here.
userModel = userModel
}.done { initModel in
// Use it here
guard let userModel = userModel else {
return
}
SandboxService.deviceServerServiceCaller(secretID: "")
// after you are done, set it to nil
userModel = nil
}.catch { error in
}
}
}
If it wasn't a framework, you could write functions in a way that you could include userModel in second callback as well.
Upvotes: 1