简体   繁体   中英

How to pass data from using POST/form leaf template?

I have a couple of major gaps in my understanding of vapor/leaf/html. I am working from the "todo" example that is created using the beta branch of vapor.

First, I made my own fluent model (no problems that I know of):

import FluentSQLite
import Vapor
final class affordatmodel: SQLiteModel {
    var id: Int?
    var propertyCost: String
    var targetEquity: String
    var interestRate: String
    var amortization: String
    var sponsor1: String
    var sponsor2: String
    var rent: String
    var rentInflation: String
    var propertyTaxes: String
    var propertyTaxesInflation: String
    var strataFees: String
    var strataFeesInflation: String
    init(propertyCost: String, targetEquity: String, interestRate: String, amortization: String, sponsor1: String, sponsor2: String, rent: String, rentInflation: String, propertyTaxes: String, propertyTaxesInflation: String, strataFees: String, strataFeesInflation: String) {
        self.propertyCost = propertyCost
        self.targetEquity = targetEquity
        self.interestRate = interestRate
        self.amortization = amortization
        self.sponsor1 = sponsor1
        self.sponsor2 = sponsor2
        self.rent = rent
        self.rentInflation = rentInflation
        self.propertyTaxes = propertyTaxes
        self.propertyTaxesInflation = propertyTaxesInflation
        self.strataFees = strataFees
        self.strataFeesInflation = strataFeesInflation
    }
}
/// Allows to be used as a dynamic migration.
extension affordatmodel: Migration { }
/// Allows to be encoded to and decoded from HTTP messages.
extension affordatmodel: Content { }
/// Allows to be used as a dynamic parameter in route definitions.
extension affordatmodel: Parameter { }

Then I make an instance and send it to a leaf template:

let defaultData = affordatmodel(propertyCost: "700000", targetEquity: "300000", interestRate: "1", amortization: "20", sponsor1: "500000", sponsor2: "200000", rent: "1200", rentInflation: "1", propertyTaxes: "8000", propertyTaxesInflation: "1", strataFees: "0", strataFeesInflation: "0")
return leaf.render("welcome", ["affordat": defaultData])

And my Leaf template successfully populates the html with the default data (body shown here):

<body class="container">
    <h1>Payment and Principal Calculations</h1>

    <form action="/affordat" method="POST">
        <div class="form-group">
            <label for="propertyCost">Property Cost</label>
            <input type="number" class="form-control" name="propertyCost" placeholder="#(affordat.propertyCost)">
                </div>
        <div class="form-group">
            <label for="targetEquity">Target Equity</label>
            <input type="number" class="form-control" name="targetEquity" placeholder="#(affordat.targetEquity)">
                </div>
        <div class="form-group">
            <label for="interestRate">Interest Rate</label>
            <input type="number" class="form-control" name="interestRate" placeholder="#(affordat.interestRate)">
                </div>
        <div class="form-group">
            <label for="amortization">Amortization (years)</label>
            <input type="number" class="form-control" name="amortization" placeholder="#(affordat.amortization)">
                </div>
        <div class="form-group">
            <label for="sponsor1">Sponsor 1 Funds</label>
            <input type="number" class="form-control" name="sponsor1" placeholder="#(affordat.sponsor1)">
                </div>
        <div class="form-group">
            <label for="sponsor2">Sponsor 2 Funds</label>
            <input type="number" class="form-control" name="sponsor2" placeholder="#(affordat.sponsor2)">
                </div>
        <div class="form-group">
            <label for="rent">Rent</label>
            <input type="number" class="form-control" name="rent" placeholder="#(affordat.rent)">
                </div>
        <div class="form-group">
            <label for="rentInflation">Rent Inflation (will be used exactly)</label>
            <input type="number" class="form-control" name="rentInflation" placeholder="#(affordat.rentInflation)">
                </div>
        <div class="form-group">
            <label for="propertyTaxes">Property Taxes (first year est.)</label>
            <input type="number" class="form-control" name="propertyTaxes" placeholder="#(affordat.propertyTaxes)">
                </div>
        <div class="form-group">
            <label for="propertyTaxesInflation">Property Taxes Inflation (est.)</label>
            <input type="number" class="form-control" name="propertyTaxesInflation" placeholder="#(affordat.propertyTaxesInflation)">
                </div>
        <div class="form-group">
            <label for="strataFees">Strata Fees (first year est.)</label>
            <input type="number" class="form-control" name="strataFees" placeholder="#(affordat.strataFees)">
                </div>
        <div class="form-group">
            <label for="strataFeesInflation">Strata Fees Inflation (est.)</label>
            <input type="number" class="form-control" name="strataFeesInflation" placeholder="#(affordat.strataFeesInflation)">
                </div>

        <input type="hidden" name="_csrf" value="{{csrfToken}}">
            <button type="submit" class="btn btn-primary">Refresh Calculations</button>
            </form>

</body>

Great, so I know how to get fluent data to HTML. My problem is I don't know how to get it back. When the "Post" occurs, the data does not seem to get passed to the controller. My route is:

router.post("affordat", use: affordatController.create)

And the relevant part of my controller looks like this:

import Vapor
final class AffordatController {
    func create(_ req: Request) throws -> Future<affordatmodel> {
        return try req.content.decode(affordatmodel.self).flatMap(to: affordatmodel.self) { affordatmodel1 in
            return affordatmodel1.save(on: req)
        }
    }
}

Which shows me one of my models, with an ID #, but no data. And I kind of understand why because I didn't really seem to send the post data to the controller. How I am supposed to send the POST data to the controller? Is the problem in my leaf template, my route, or my controller?

It looks like it should work. You can inspect the data being sent to your server in the network inspector in your browser. Make sure you preserve logs and you'll be able to see the POST request and the data sent to the server.

If you breakpoint at each point in the request you can see what the data is.

As an aside, it looks like you're submitting an empty form, so it's just filling everything in as blank strings. Do you mean to use value instead of placeholder in the form inputs? Value will pre-populate the data for the user, placeholder will show the value to the user as a suggestion but won't send the data in the form submission.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM