Reputation: 306
I have a Group, User and an App model. Within my Group model, I have a property var apps: [App]
and I create a sibling relationship bw Group and User.
In my WebsiteController, I have 2 handlers:
createGroupHandler
which handles the GET request at /groups/createcreateGroupPostHandler
which handles the POST request at /groups/createMy problem is that after selecting app objects in my form in my createGroup.leaf template, when I create my new group no apps are being populated into my apps array.
I created structs to represent the context being rendered in my createGroupHandler
and to handle the data being passed in the post request for createGroupPostHandler
struct CreateGroupContext: Encodable {
let title = "Create Group"
let users: Future<[User]>
let apps: Future<[App]>
}
struct CreateGroupData: Content {
let name: String
let apps: [App]
let users: [String]?
}
The apps are properly loaded into the form but despite selecting them like in the image below, they aren't added to the array
My createGroupPostHandler
looks like below. I don't know how to grab the selected apps and populate my apps: [App]
array when I create my group is my issue, I feel like this is where I should be doing that, but I don't know how to grab that from the Leaf template.
func createGroupPostHandler(_ req: Request, data: CreateGroupData) throws -> Future<Response> {
let group = Group(name: data.name, apps: data.apps)
return group.save(on: req).flatMap(to: Response.self) { group in
guard let id = group.id else {
throw Abort(.internalServerError)
}
var userSaves: [Future<Void>] = []
for user in data.users ?? [] {
try userSaves.append(User.addUser(user, to: group, on: req))
}
let redirect = req.redirect(to: "/groups/\(id)")
return userSaves.flatten(on: req).transform(to: redirect)
}
}
This is what my createGroup.leaf looks like:
Upvotes: 1
Views: 970
Reputation: 5200
I use index notation of naming input
tags in HTML, such as score[0]
, score[1]
, etc. Vapor is then quite happy to parse this and create a dictionary (okay, technically not an array!).
Use this notation in the Leaf file:
#for(result in results) {
<input type="text" name="score[#(index)]" value="#(result.score)">
}
The controller function:
struct SaveResult:Content
{
var score:[Int:String]
}
func saveRoll(_ request:Request) throws -> Future<View>
{
return try request.content.decode(SaveResult.self).flatMap
{
result in
for i in 0...(result.score.count) - 1
{
print( detail.score[i] )
}
return try self.index(request)
}
}
Upvotes: 1