Reputation: 3422
I have a frontend rails app that is requesting a rails API. When my user wants to create an account, he is submitting the account form on the front-end app :
<h1>Create Account</h1>
<form action="http://localhost:3000/accounts" method="post">
<input name="authenticity_token" value="<%= form_authenticity_token %>" type="hidden">
<div class="form-group">
<%= label_tag 'account[name]', "name" %>
<input type="text" name="account[name]" required>
</div>
<div class="form-group">
<%= label_tag "account[contact_mail]", "E-Mail" %>
<input type="text" name= "account[contact_mail]" required>
</div>
<div class="form-group">
<%= label_tag "account[contact_tel]", "Telephone" %>
<input type="text" name= "account[contact_tel]" required>
</div>
<div class="form-group">
<%= label_tag "account[iban]", "Iban" %>
<input type="text" name= "account[iban]">
</div>
<div class="form-group">
<%= label_tag "account[bic]", "Bic" %>
<input type="text" name= "account[bic]">
</div>
<input type="submit">
<% if @errors %>
<ul class="list-unstyled">
<%@errors.each do |error|%>
<li class="has-error"><%=error%></li>
<% end -%>
</ul>
<% end -%>
</form>
On submit the method create
from the front-end app account controller
is called. The create
method from the front-end app is then calling the create
method on the rails API which is responsible for updating the database and rendering JSON to the front end app.
1) AccountController#create
from the front-end app :
def create
# Post sur API create Account
@response = HTTParty.post(ENV['API_ADDRESS']+'api/v1/accounts',
:body => { :name => params[:account][:name],
:contact_mail => params[:account][:contact_mail],
:contact_tel => params[:account][:contact_tel],
:legal_status => params[:account][:legal_status],
:iban => params[:account][:iban],
:bic => params[:account][:bic]
}.to_json,
:headers => { 'X-User-Email' => session[:user_email], 'X-User-Token'=> session[:user_token], 'Content-Type' => 'application/json' } )
# Erreur Mauvais Auth Token
if @response["error"] == "You need to sign in or sign up before continuing."
redirect_to unauthorized_path
# erreur de validation
elsif @response["errors"]
@errors = @response["errors"]
flash[:alert] = "heello"
render :new
else
account_id = @response["account"]["id"]
redirect_to account_path(account_id)
end
end
2) AccountController#create
from the API :
def create @account = Account.new(account_params.merge(admin: current_user)) authorize @account if @account.save render :show else render_error end end
render error
is a method that render errors in JSON format :
def render_error
render json: { errors: @account.errors.full_messages }, status: :unprocessable_entity
end
If there are validations errors when submitting the from to the API, I display them on the front end app next to the form :
<% if @errors %>
<ul class="list-unstyled">
<%@errors.each do |error|%>
<li class="has-error"><%=error%></li>
<% end -%>
</ul>
My problem is that I also wish to prepopulate the form with the data the user already submitted for better user experience.
I know there are already posts about how to prepopulate forms with rails in case of validation errors but I feel they did not really address my problem with this "double app pattern" and with my front-end app not having any models (all models / DB interactions are dealt in the API)
How can I prepopulate my form with the user's input after I receive an error from my JSON API ?
Upvotes: 0
Views: 198
Reputation: 240
In the form you have, you could add value attributes to the input fields that populate with irb instance variables
<input type="text" name="account[name]" value="<%= @account_name %>" required>
Then in AccountController#create
, set the instance variables based on the the params you received when you want to display the invalid data.
```
elsif @response["errors"]
@errors = @response["errors"]
#new code
@account_name = params[:account][:name]
#set each variable, extra to method or class for cleaner style
flash[:alert] = "heello"
render :new
```
When the form initially renders these variables will be uninitialize/nil so there will be no values in the form boxes, and then you can explicitly set them in the controller when the validation fails but you want to maintain data in the form.
This is definitely an overly-manual way to accomplish maintaining the form state, and I suggest if you want to reuse the pattern in your app you take a look at using form_for. This post might give you some insight into doing that with plain ruby objects instead of model objects. Is it possible to create form for simple class
Upvotes: 1