I’ve been trying to develop a Vapor web app as a demo of an API wrapper I built in Swift. Right now I have a function that returns an Encodable object, and I’m trying to pass it into leaf to display the info. However, I’ve been having a hard time getting Async to work with it and making sure Vapor waits for the data before presenting the template.
Right now my code compiles but the template is presented without the data.
Here’s the route in question:
final class RoomController {
// Registers Room routes.
func addRoutes(_ router: Router) {
let room = router.grouped("room")
room.get("/", use: self.room)
}
// Handles root Room endpoint.
func room(_ req: Request) throws -> Future<View> {
let config = TokenConfiguration("TOKEN")
let dataPromise = req.eventLoop.newPromise(Room.self) // Miserable attempt at creating a data promise
let _ = UCLKit(config).rooms() { response in // Call to my Framework.
switch response {
case .success(let roomsResponse):
print(roomsResponse.rooms![0].roomName!) // Successfuly prints data, so it should be working.
dataPromise.succeed(result: roomsResponse.rooms![0]) // Attempt at fullfiling promise.
case .failure(let error):
dataPromise.fail(error: error)
}
}
return try req.view().render("Room", dataPromise.futureResult) // Return rendered templatre with future result.
}
}
Well I also don’t want to limit the entire framework to Vapor, most people don’t use promises, rewriting the entire framework to return futures by default seems a bit overkill
So rooms[0] is the first room from the response.
This is reflected as:
/// Wrapper for the Rooms response
@objc public final class RoomsResponse: NSObject, Codable {
open var OK: Bool?
open var error: String?
open var rooms: [Room]?
enum CodingKeys: String, CodingKey {
case OK = "ok"
case error
case rooms
}
}
/// Payload from the Rooms response
@objc public final class Room: NSObject, Codable {
@objc open var roomID: String?
@objc open var roomName: String?
@objc open var siteID: String?
@objc open var siteName: String?
open var capacity: Int?
open var classification: Classification?
open var automated: Automation?
@objc open var location: Location?
enum CodingKeys: String, CodingKey {
case roomID = "roomid"
case roomName = "roomname"
case siteID = "siteid"
case siteName = "sitename"
case capacity
case classification
case automated
case location
}
}
...
Oh that’s interesting! I can confirm it works, thanks a lot!
So, is there a reason why Leaf uses the codingKeys (which I originally used to just parse the API JSON into the object)?
@tiferrei because Leaf uses Codable then the coding keys affect it as well. So it would be the same if you were to use Fluent to save that into a database etc