Reputation: 11
I'm new to coding in general and the concept of futures especially so patience would be appreciated! The goal of the following function is to check whether or not an account exists in a PostgreSQL database. If it does, return an empty UUID; if no account exists, create a new one and return its UUID. When I try to run my code, the error Cannot convert return expression of type 'EventLoopFuture<Account.idOut>' to return type 'Account.idOut'
appears next to the line .map { Account.idOut(id: account.id!) }
. I've looked around here already and can't seem to find any solution to this problem. Any help would be appreciated, thanks!!
func newAccount(req: Request) throws -> EventLoopFuture<Account.idOut> {
let input = try req.content.decode(Account.postAccount.self)
//check to see if account already exists
return Account.query(on: req.db)
.filter(\.$email == input.email)
.first().map { checkAccount in
if checkAccount == nil {
let id = UUID()
let account = Account(id: id, fullName: input.fullName, email: input.email, password: input.password, type: input.type)
return account.save(on: req.db)
.map { Account.idOut(id: account.id!) }
} else {
return Account.idOut(id: UUID("00000000-0000-0000-0000-000000000000")!)
}
}
}
Upvotes: 0
Views: 678
Reputation: 5585
In short, you need to return the same type to satisfy the compiler. This can definitely get a bit confusing with an if
/else
like yours where one returns a future and one doesn't. The way around it, is to return a future for both like so:
func newAccount(req: Request) throws -> EventLoopFuture<Account.idOut> {
let input = try req.content.decode(Account.postAccount.self)
//check to see if account already exists
return Account.query(on: req.db)
.filter(\.$email == input.email)
.first().flatMap { checkAccount in
if checkAccount == nil {
let id = UUID()
let account = Account(id: id, fullName: input.fullName, email: input.email, password: input.password, type: input.type)
return account.create(on: req.db)
.map { Account.idOut(id: account.id!) }
} else {
return req.eventLoop.future(Account.idOut(id: UUID("00000000-0000-0000-0000-000000000000")!))
}
}
}
Important things to note:
map
to a flatMap
since you're returning a future insidecreate
instead of save
for the save operation as you're providing an ID and this forces Fluent to create the model. (Fluent will usually set the ID for you)req.eventLoop.future
- this returns EventLoopFuture<Account.idOut>
which satisfies the compilerUpvotes: 2