<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="153034" data-post-id="153034">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="peerreynders" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/120/5826_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  peerreynders
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group quote-modified" data-username="thiagomajesk" data-post="11" data-topic="27249">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/thiagomajesk/48/31904_2.png" class="avatar"> thiagomajesk:</div>
<blockquote>
<p>That’s very interesting because in aspnet the action on the form would be just “create”, so if there’s an error it wouldn’t change the url (which I find weird).</p>
</blockquote>
</aside>
<p>My impression from <a href="http://ASP.NET" rel="noopener nofollow ugc">ASP.NET</a> webforms was that it tried to emulate desktop apps on the web and from that perspective pages were treated as <em>screens</em> - so if you were creating something you’re stuck on the “create screen” until you get it right.</p>
<p>I rationalize the Phoenix approach with the REST-model of the Web</p>
<ul>
<li><code>/users/new</code> is the URL to <code>GET</code> the (fresh) form that is capable of creating a new user</li>
<li>That form <code>POST</code>s to <code>/users</code> in an attempt to create a new user</li>
<li>The error page is the response to the failed creation of a user from the <code>/users</code> resource</li>
<li>Upon successful creation the <code>/users</code> resource issues a redirect to the new resource <code>/users/{id}</code>.</li>
</ul>
<blockquote>
<p>and then uses a convention to select the “create” action,</p>
</blockquote>
<p>It’s not convention, it’s in the routing:<br>
<a href="https://media.pragprog.com/titles/phoenix14/code/ecto/listings/rumbl/lib/rumbl_web/router.change1.ex" class="onebox" target="_blank" rel="noopener nofollow ugc">https://media.pragprog.com/titles/phoenix14/code/ecto/listings/rumbl/lib/rumbl_web/router.change1.ex</a></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  scope "/", RumblWeb do
    pipe_through :browser

    get "/", PageController, :index
    resources "/users", UserController, only: [:index, :show, :new, :create]
  end
</code></pre>
<aside class="onebox allowlistedgeneric" data-onebox-src="https://phoenix.hexdocs.pm/Phoenix.Router.html">
  <header class="source">

      <a href="https://phoenix.hexdocs.pm/Phoenix.Router.html" target="_blank" rel="noopener nofollow ugc">phoenix.hexdocs.pm</a>
  </header>

  <article class="onebox-body">
    

<h3><a href="https://phoenix.hexdocs.pm/Phoenix.Router.html" target="_blank" rel="noopener nofollow ugc">Phoenix.Router — Phoenix v1.8.8</a></h3>



  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>

<p>The <code>resources/4</code> macro’s conventions (without the <code>:singleton</code> option):</p>
<blockquote>
<ul>
<li><code>GET /users</code>  =&gt;  <code>:index</code></li>
<li><code>GET /users/new</code>  =&gt;  <code>:new</code></li>
<li><code>POST /users</code>  =&gt;  <code>:create</code></li>
<li><code>GET /users/:id</code>  =&gt;  <code>:show</code></li>
<li><code>GET /users/:id/edit</code>  =&gt;  <code>:edit</code></li>
<li><code>PATCH /users/:id</code>  =&gt;  <code>:update</code></li>
<li><code>PUT /users/:id</code>  =&gt;  <code>:update</code></li>
<li><code>DELETE /users/:id</code>  =&gt;  <code>:delete</code></li>
</ul>
</blockquote>
<pre><code class="lang-plaintext">$ mix phx.routes
   page_path  GET     /                        RumblWeb.PageController :index
   user_path  GET     /users                   RumblWeb.UserController :index
   user_path  GET     /users/new               RumblWeb.UserController :new
   user_path  GET     /users/:id               RumblWeb.UserController :show
   user_path  POST    /users                   RumblWeb.UserController :create
...
$</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="153034" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/is-prg-a-valid-technique-in-phoenix/27249/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-153034" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="153034"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="153050" data-post-id="153050">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="thiagomajesk" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/thiagomajesk/120/31904_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  thiagomajesk
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group quote-modified" data-username="peerreynders" data-post="12" data-topic="27249">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/48/5826_2.png" class="avatar"> peerreynders:</div>
<blockquote>
<p>My impression from <a href="http://ASP.NET" rel="noopener nofollow ugc">ASP.NET</a> webforms was that it tried to emulate desktop apps on the web and from that perspective pages where treated as <em>screens</em> - so if you were creating something your we’re stuck on the “create screen”.</p>
</blockquote>
</aside>
<p>I’m actually talking about aspnet mvc (not webforms) which works very much like other web mvc frameworks out there. I’ve made a little research and found that Laravel behaves more like aspnet while Phoenix does exactly the same thing that Rails does which is changing the url on post.</p>
<p>After playing with some code over here, I think I finally got what’s happening. Just to draw a comparison…<br>
When you create a controller in aspnet, the default routing convention is to use the method names in the controller to compose the route. So if you have a <code>User</code> controller and a method named <code>New</code> then you have an exposed route called <code>~/user/new</code> automatically. In Phoenix the “create” function is not known as a route, so you can’t use that on the form action. Then, the thing I was finding unsettling is that, since the browser will follow the form action on submit, there’s this minor difference on the route that changes. (you learn something new every day <img src="https://forum.elixirforum.com/images/emoji/apple/smile.png?v=15" title=":smile:" class="emoji" alt=":smile:" loading="lazy" width="20" height="20">). Also, thanks for the explanation <a class="mention" href="/u/peerreynders" rel="nofollow">@peerreynders</a>.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="153050" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/is-prg-a-valid-technique-in-phoenix/27249/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-153050" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="153050"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="153052" data-post-id="153052">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="thiagomajesk" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/thiagomajesk/120/31904_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  thiagomajesk
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>So, getting back on the topic about the PRG pattern… What are the options here (if any)?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="153052" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/is-prg-a-valid-technique-in-phoenix/27249/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-153052" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="153052"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="153061" data-post-id="153061">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="peerreynders" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/120/5826_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  peerreynders
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>To me it’s not clear what your remaining issues are - other than perhaps a misaligned mental model which can easily happen when moving between frameworks.</p>
<p>A far as I can tell <a href="https://en.wikipedia.org/wiki/Post/Redirect/Get" rel="noopener nofollow ugc">Post/Redirect/Get</a> is what is happening in</p>
<p><a href="https://media.pragprog.com/titles/phoenix14/code/ecto/listings/rumbl/lib/rumbl_web/controllers/user_controller.change3.ex" class="onebox" target="_blank" rel="noopener nofollow ugc">https://media.pragprog.com/titles/phoenix14/code/ecto/listings/rumbl/lib/rumbl_web/controllers/user_controller.change3.ex</a></p>
<p>in the success case - though perhaps <code>create</code> should redirect to <code>show</code> rather than <code>index</code>.</p>
<blockquote>
<p>Then, when you submit your form, the resulting action of the post is <strong>always</strong> a redirect…</p>
</blockquote>
<p>I don’t see any reference of what is supposed to happen in the failure case.</p>
<aside class="onebox stackexchange" data-onebox-src="https://stackoverflow.com/questions/599086/how-are-server-side-errors-handled-in-post-redirect-get-pattern">
  <header class="source">

      <a href="https://stackoverflow.com/questions/599086/how-are-server-side-errors-handled-in-post-redirect-get-pattern" target="_blank" rel="noopener nofollow ugc">stackoverflow.com</a>
  </header>

  <article class="onebox-body">
      <a href="https://stackoverflow.com/users/72356/wayne-see" target="_blank" rel="noopener nofollow ugc">
    <img alt="Wayne See" src="https://www.gravatar.com/avatar/483707a2b5b45bde072938f17a91a89b?s=256&amp;d=identicon&amp;r=PG" class="thumbnail onebox-avatar" width="256" height="256">
  </a>

<h4>
  <a href="https://stackoverflow.com/questions/599086/how-are-server-side-errors-handled-in-post-redirect-get-pattern" target="_blank" rel="noopener nofollow ugc">How are server side errors handled in Post/Redirect/Get pattern?</a>
</h4>

<div class="tags">
  <strong>post-redirect-get</strong>
</div>

<div class="date">
  asked by
  
  <a href="https://stackoverflow.com/users/72356/wayne-see" target="_blank" rel="noopener nofollow ugc">
    Wayne See
  </a>
  on <a href="https://stackoverflow.com/questions/599086/how-are-server-side-errors-handled-in-post-redirect-get-pattern" target="_blank" rel="noopener nofollow ugc">02:03AM - 01 Mar 09 UTC</a>
</div>

  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>

<blockquote>
<p>With PRG, we would make the “new” action always responsible for knowing how to build the form.</p>
</blockquote>
<p>This is where there is some potential misalignment - it’s the view (<code>new.html.eex</code>) which builds the form - both the <code>new</code> and <code>create</code> functions have the responsibility of providing the necessary data for the view to do its job.</p>
<ul>
<li>the <code>car_colors</code>/<code>car_optionals</code> issue is typically resolved with extracting a common function (likely a context function)</li>
<li>alternate solution: cache the encoded data in the server side session so the failure case doesn’t have to hit the database again (but the result could still be in the RDBMS cache anyway).</li>
</ul>
<blockquote>
<p>I guess that if the server is always responding with a 200, it’s still a “valid form submission” for the browser’s point fo view (usually, frameworks don’t return a 500 when there’s a validation problem).</p>
</blockquote>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/200" rel="noopener nofollow ugc"><code>200 OK</code></a></p>
<blockquote>
<p>The HTTP <code>200 OK</code> success status response code indicates that the request has succeeded.</p>
</blockquote>
<p>The request has succeeded inasfar it was able to reply with a meaningful response - the error page.</p>
<p>If a new resource is created the redirect will cause a <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/302" rel="noopener nofollow ugc"><code>302 Found</code></a> (ideally it should be <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/303" rel="noopener nofollow ugc"><code>303 See Other</code></a> (<a href="https://hexdocs.pm/plug/Plug.Conn.html#put_status/2" rel="noopener nofollow ugc"><code>Plug.Conn.put_status/2</code></a>) while an API should simply use <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/201" rel="noopener nofollow ugc"><code>201 created</code></a> but that wouldn’t cause a redirect on a browser).</p>
<p>So the fundamental problem doesn’t seem to be the PRG pattern but the fact that you would like the <code>new</code> function to be solely responsible for the “new form” - and Phoenix doesn’t work that way.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="153061" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/is-prg-a-valid-technique-in-phoenix/27249/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-153061" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="153061"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="153083" data-post-id="153083">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="thiagomajesk" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/thiagomajesk/120/31904_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  thiagomajesk
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="peerreynders" data-post="15" data-topic="27249">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/48/5826_2.png" class="avatar"> peerreynders:</div>
<blockquote>
<p>To me it’s not clear what your remaining issues are - other than perhaps a misaligned mental model which can easily happen when moving between frameworks.</p>
</blockquote>
</aside>
<p>That’s for sure one of the reasons I brought this topic for discussion.</p>
<p>But regarding the PRG pattern in general, if you check the Wikipedia article, you’ll see that it states that any post request should be followed by a redirect, not only “successful” ones. This, of course, helps in some cases:</p>
<p><strong>Side note:</strong> I even saw someone on Stack Overflow suggesting the <strong>Strict PRG</strong> and <strong>Loose PRG</strong> terminology - I’m talking mainly about using the former since the latter is already used by default.</p>
<ul>
<li>Avoid form resubmission on page refresh or navigation</li>
<li>Bookmarks (keeping resource “state”)</li>
<li>Form data building (SRP by extension)</li>
</ul>
<p>Currently, only the last issue can be solved - by reusing the code (which does not depend on the framework).</p>
<p>In the Stack Overflow thread you linked, there are some assumptions on the “Loose PRG” type mainly because it does not touch more uses-cases for the “Strict PRG” approach, for example…</p>
<p>About the form resubmission issue: <a href="https://forum.elixirforum.com/t/is-prg-a-valid-technique-in-phoenix/27249/8" rel="nofollow">as I explained here</a>, it still may be undesirable to allow that behavior, which might turn into a UX problem.</p>
<p>For bookmarks (in the specific case of Phoenix ), there’s that particularity about the routes. By default, if the form contains invalid data, <code>~/user/create</code> becomes <code>~/user</code> and <code>~/user/1/edit</code> becomes <code>~/user/1</code> which both are different views (templates) if accessed without the operation context. Then, if the user is presented with an error and I ask him to send me the url where the problem happened, that will be an issue (of course, this is the most simplistic use-case I could think of).</p>
<p>Regarding rebuilding the view, I’ve seen people argue that using the post action to render a view violates REST. I’m not completely sure if this is technically correct, but it’d be good to allow that when possible as a best practice IMO.</p>
<aside class="quote no-group" data-username="peerreynders" data-post="15" data-topic="27249">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/48/5826_2.png" class="avatar"> peerreynders:</div>
<blockquote>
<p>This is where there is some potential misalignment - it’s the view ( <code>new.html.eex</code> ) which builds the form - both the <code>new</code> and <code>create</code> functions have the responsibility of providing the necessary data for the view to do its job.</p>
</blockquote>
</aside>
<p>I couldn’t agree more (I kept my last paragraph for reference). Thinking that way, I guess you are saying that the view is responsible for rendering the template, so I’m assuming you are also saying that there’s not SRP problem (Could you expand on that?). If so (and that’s also the case), would it still be a REST violation, considering that the action is started by the controller (because the view is used indirectly for the same purpose)?</p>
<aside class="quote no-group" data-username="peerreynders" data-post="15" data-topic="27249">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/48/5826_2.png" class="avatar"> peerreynders:</div>
<blockquote>
<p>So the fundamental problem doesn’t seem to be the PRG pattern but the fact that you would like the <code>new</code> function to be solely responsible for the “new form” - and Phoenix doesn’t work that way.</p>
</blockquote>
</aside>
<p>Not exactly, but I think that this is covered by what I’ve already mentioned.<br>
Also, as you already pointed out before, I’m adapting my mental model by trying to see what could/ should be transferred to Phoenix. So I think is plausible to have these exchanges on how others are approaching it - it’s certainly productive to me, at least.</p>
<blockquote>
<p>and Phoenix doesn’t work that way</p>
</blockquote>
<p>I opened this thread already thinking that since everything has to be passed explicitly as a param it probably couldn’t be achieved - since the “Strict PRG” presumes that the form-state data has to be sent over on the redirect (or at least kept in some way).</p>
<p><strong>PS.:</strong> Was searching for solutions in other frameworks and stumbled upon this rails gem called <a href="https://github.com/tommeier/rails-prg" rel="noopener nofollow ugc">rails-prg</a>. It seems that there’s another issue that PRG solves that I was not aware of - don’t know if this affects Phoenix too, but thought would be nice to share.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="153083" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/is-prg-a-valid-technique-in-phoenix/27249/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-153083" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="153083"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="153118" data-post-id="153118">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="peerreynders" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/120/5826_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  peerreynders
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="thiagomajesk" data-post="16" data-topic="27249">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/thiagomajesk/48/31904_2.png" class="avatar"> thiagomajesk:</div>
<blockquote>
<p>I even saw someone on Stack Overflow suggesting the <strong>Strict PRG</strong> and <strong>Loose PRG</strong> terminology</p>
</blockquote>
</aside>
<aside class="onebox stackexchange" data-onebox-src="https://stackoverflow.com/questions/8178821/is-there-a-name-for-the-prg-pattern-that-doesnt-redirect-on-failed-validation">
  <header class="source">

      <a href="https://stackoverflow.com/questions/8178821/is-there-a-name-for-the-prg-pattern-that-doesnt-redirect-on-failed-validation" target="_blank" rel="noopener nofollow ugc">stackoverflow.com</a>
  </header>

  <article class="onebox-body">
      <a href="https://stackoverflow.com/users/272072/scott-rippey" target="_blank" rel="noopener nofollow ugc">
    <img alt="Scott Rippey" src="https://www.gravatar.com/avatar/91d87be289785dede0ef9385c3d33dba?s=256&amp;d=identicon&amp;r=PG" class="thumbnail onebox-avatar" width="256" height="256">
  </a>

<h4>
  <a href="https://stackoverflow.com/questions/8178821/is-there-a-name-for-the-prg-pattern-that-doesnt-redirect-on-failed-validation" target="_blank" rel="noopener nofollow ugc">Is there a name for the PRG pattern that doesn't redirect on failed validation?</a>
</h4>

<div class="tags">
  <strong>asp.net-mvc, post-redirect-get</strong>
</div>

<div class="date">
  asked by
  
  <a href="https://stackoverflow.com/users/272072/scott-rippey" target="_blank" rel="noopener nofollow ugc">
    Scott Rippey
  </a>
  on <a href="https://stackoverflow.com/questions/8178821/is-there-a-name-for-the-prg-pattern-that-doesnt-redirect-on-failed-validation" target="_blank" rel="noopener nofollow ugc">06:55AM - 18 Nov 11 UTC</a>
</div>

  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>

<p>Professional <a href="http://ASP.NET" rel="noopener nofollow ugc">ASP.NET</a> MVC 2 (2010) attributes that to Phil Haack</p>
<blockquote>
<p>Note that redirecting the request only upon success technically violates the PRG pattern, <em>but because no changes where made to the state of anything when validation failed</em>, it doesn’t suffer from most of the problems with not following the PRG pattern. Phil likes to call this <em>loose PRG</em> as opposed to <em>strict PRG</em>.</p>
</blockquote>
<p>The pattern itself seems to go back to this 2004 article/2003 discussion:</p>
<aside class="onebox allowlistedgeneric" data-onebox-src="https://www.theserverside.com/news/1365146/Redirect-After-Post">
  <header class="source">
      <img src="https://www.theserverside.com/favicon.ico" class="site-icon" alt="" width="512" height="512">

      <a href="https://www.theserverside.com/news/1365146/Redirect-After-Post" target="_blank" rel="noopener nofollow ugc">TheServerSide.com</a>
  </header>

  <article class="onebox-body">
    <img width="" height="" src="https://www.theserverside.com/ITKE/images/logos/TTlogo-379x201.png" class="thumbnail" alt="">

<h3><a href="https://www.theserverside.com/news/1365146/Redirect-After-Post" target="_blank" rel="noopener nofollow ugc">Redirect After Post | TheServerSide</a></h3>

  <p>This article shows how to design a well-behaved web application using redirection.</p>


  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>

<aside class="onebox allowlistedgeneric" data-onebox-src="https://www.theserverside.com/">
  <header class="source">
      <img src="https://www.theserverside.com/favicon.ico" class="site-icon" alt="" width="512" height="512">

      <a href="https://www.theserverside.com/" target="_blank" rel="noopener nofollow ugc">theserverside.com</a>
  </header>

  <article class="onebox-body">
    

<h3><a href="https://www.theserverside.com/" target="_blank" rel="noopener nofollow ugc">TheServerSide | Your Java Community discussing server side development</a></h3>

  <p>Java developers discussing Java J2EE, java software, Java programming and other trends in server side development</p>


  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>

<blockquote>
<p>This approach provides a clean Model-View-Controller solution.</p>
</blockquote>
<p>Aside: Server MVC has always played it fast and loose with Trygve Reenskaug MVC.</p>
<aside class="quote quote-modified" data-post="12" data-topic="17190">
  <div class="title">
    <div class="quote-controls"></div>
    <img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/48/5826_2.png" class="avatar">
    <div class="quote-title__text-content">
      <a href="https://forum.elixirforum.com/t/discussion-about-domain-orientated-folder-structures-in-phoenix/17190/12" rel="nofollow">Discussion about domain-orientated folder structures in Phoenix</a> <a class="badge-category__wrapper " href="/c/chat-discussions/chat-discussions/167" rel="nofollow"><span data-category-id="167" style="--category-badge-color: #cca771; --category-badge-text-color: #FFFFFF; --parent-category-badge-color: #cca771;" data-parent-category-id="165" data-drop-close="true" class="badge-category --style-square --has-parent"><span class="badge-category__name">Discussions</span></span></a>
    </div>
  </div>
  <blockquote>
    To elaborate: 
MVC has been subject to re-interpretation over the years - almost to the point of meaninglessness. The web model (Server MVC) goes back to the <a href="http://www.kirkdorffer.com/jspspecs/jsp092.html#model" rel="noopener nofollow ugc">JSP Model 2 Archtecture (1998)</a> - and really only has a vague resemblance to the pattern outlined in 1979 by Trygve Reenskaug. 
[model2] 
<a href="https://paulhammant.com/2015/04/29/mvc-misunderstood-for-37-years/" rel="noopener nofollow ugc">MVC: misunderstood for 37 years</a> 
<a href="https://givan.se/mvc-past-present-and-future/" rel="noopener nofollow ugc">MVC past, present and future.</a> 
<a href="https://mvc.givan.se/%5D" rel="noopener nofollow ugc">MVC Tree</a> 
<a href="http://wiki.c2.com/?WhatsaControllerAnyway" rel="noopener nofollow ugc">Whats a Controller Anyway?</a> 
<a href="https://www.amazon.com/Pattern-Oriented-Software-Architecture-System-Patterns/dp/0471958697" rel="noopener nofollow ugc">POSA1</a> gets into Trygve’s MVC and describes the distribution of responsibilities as : 
View: 

Creates …
  </blockquote>
</aside>

<blockquote>
<p>But please dear browser, do not save snapshots of a live program, because they may not represent actual Model state anymore.<br>
…<br>
Now I ask the same question again: what would a user see if he clicks Back button after submitting a form? You know the correct answer already: the user of a well-designed web application would see a View which represents current Model state. This View would be presented in a way that resubmitting of the same data would be impossible.</p>
</blockquote>
<p>Sorry, in <a href="https://developers.google.com/web/updates/2019/02/back-forward-cache" rel="noopener nofollow ugc">2019</a> browsers still don’t work that way (<a href="https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Inner_and_outer_windows" rel="noopener nofollow ugc">bfcache, “Backward-Forward Cache”</a>). Even after a successful redirect I can back up to the submit form and those last valid values will reappear in the form fields and I can click that submit button again.</p>
<p>If you need to defeat cached pages you need to employ <a href="https://css-tricks.com/serious-form-security/#article-header-id-0" rel="noopener nofollow ugc">token matching</a> and remove the hidden form token from the server session after the resource has been successfully created (the standard CSRF token doesn’t stop double submission from a recently cached form).</p>
<p>Browser-side the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/pageshow_event" rel="noopener nofollow ugc">pageshow</a> event could be used to clear the input fields  - but that will only work when JavaScript is enabled.</p>
<blockquote>
<p>(1) Create Item is called from a link on some other web page when a new object should be created. This action constructs empty business object and <strong>stores it in the temporary area called Current Items, which itself can be stored in the database or in the session</strong>; then redirects to Display Item.</p>
</blockquote>
<p>This suggests that each user has their <em>own</em> <code>/users/new</code> resource (otherwise it couldn’t be stored in the session) - this violates the notion that <code>/users/new</code> uniquely addresses a single resource.</p>
<blockquote>
<p>(2-2) User fills out object value and submits HTML form to the Store Item action. <strong>If object is not accepted, it is kept in the Current Items area, server redirects back to Display Item action, which reads invalid object along with error messages from the Current Items and redisplays it in the form.</strong> If Item Page needs to be is refreshed, it loads the same object from Current Items again.</p>
</blockquote>
<p>i.e. once again - my <code>/users/new</code> would show my last errors while your <code>/users/new</code> would show your last errors - so <code>/users/new</code> isn’t uniquely addressing a resource.</p>
<p>Furthermore we’re now in a situation where errors will change “model state” because the errors are part of the “model state”. So rather than saying that redirect <em>on failure</em> is a requirement, it is more to the point that redirect <em>on state change</em> is a requirement.</p>
<p>If your philosophy is to not accept invalid data then you aren’t going to store “half-baked”, inconsistent items - which is what is happening in the “Current Items” area.</p>
<blockquote>
<p>If a user clicks Back button on result page (3) after successfully creating and storing new object, he returns to Display Item action (2).</p>
</blockquote>
<p>This completely ignores the existence of the “Backward-Forward Cache” in browsers. (Though it’s presumably preventable with <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#Preventing_caching" rel="noopener nofollow ugc"><code>Cache-Control: no-store</code></a>)</p>
<p>Ultimately the article reads like somebody is trying to coerce their vision of MVC/OO onto the web.</p>
<aside class="quote no-group" data-username="thiagomajesk" data-post="16" data-topic="27249">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/thiagomajesk/48/31904_2.png" class="avatar"> thiagomajesk:</div>
<blockquote>
<p>Then, if the user is presented with an error and I ask him to send me the url where the problem happened, that will be an issue (of course, this is the most simplistic use-case I could think of).</p>
</blockquote>
</aside>
<p>As I explained above with “Current Items Storage” each user/session would have a <strong>different</strong> <code>/users/new</code> resource anyway - there is no way you could <code>GET /user/new</code> with the validation errors unless you are in the same user/session context.</p>
<p>Phoenix is pragmatic about it - the form validation errors are ephemeral - they aren’t associated with an addressable resource. The aim is to maintain only <strong>valid</strong> resources, validation errors are ephemeral (short of what is written to the log).</p>
<ul>
<li>when you <code>GET \users</code> you will always get a list of users</li>
<li>when you <code>GET \users\new</code> you will always get an empty form</li>
</ul>
<blockquote>
<p>I’ve seen people argue that using the post action to render a view violates REST.</p>
</blockquote>
<p><a href="https://tools.ietf.org/html/rfc2616#section-9.5" rel="noopener nofollow ugc">RFC 2616 9.5 POST</a></p>
<blockquote>
<p>The action performed by the POST method might not result in a resource that can be identified by a URI. In this case, either 200 (OK) or 204 (No Content) is the appropriate response status, depending on whether or not the response includes an entity that describes the result.</p>
</blockquote>
<p>So <code>200 OK</code> for the validation errors is permissible as no resource is created.</p>
<blockquote>
<p>If a resource has been created on the origin server, the response SHOULD be 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header (see section 14.30).</p>
</blockquote>
<p>This is the ideal REST case - typically used by APIs.</p>
<blockquote>
<p>However, the 303 (See Other) response can be used to direct the user agent to retrieve a cacheable resource.</p>
</blockquote>
<p>This is what is used to guide browsers to the newly created resource.</p>
<aside class="quote no-group" data-username="thiagomajesk" data-post="16" data-topic="27249">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/thiagomajesk/48/31904_2.png" class="avatar"> thiagomajesk:</div>
<blockquote>
<p>so I’m assuming you are also saying that there’s not SRP problem (Could you expand on that?)</p>
</blockquote>
</aside>
<p>FYI: SRP/SOLID</p>
<aside class="quote quote-modified" data-post="7" data-topic="14769">
  <div class="title">
    <div class="quote-controls"></div>
    <img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/48/5826_2.png" class="avatar">
    <div class="quote-title__text-content">
      <a href="https://forum.elixirforum.com/t/using-functional-design-to-reduce-arity/14769/7" rel="nofollow">Using functional design to reduce arity</a> <a class="badge-category__wrapper " href="/c/questions-help/questions/53" rel="nofollow"><span data-category-id="53" style="--category-badge-color: #C14BFB; --category-badge-text-color: #000000; --parent-category-badge-color: #C14BFB;" data-parent-category-id="171" data-drop-close="true" class="badge-category --style-square --has-parent" title="Elixir Questions / Help"><span class="badge-category__name">Questions</span></span></a>
    </div>
  </div>
  <blockquote>
    There are a lot of confused explanations for partial application and currying. 
I’m going back to why currying was invented in the first place: 
<a href="http://haskellbook.com/" rel="noopener nofollow ugc">Haskell book</a>, p.10: 

Each lambda can only bind one parameter and can only accept one argument. Functions that require multiple arguments have multiple, nested heads. When you apply it once and eliminate the first (leftmost) head, the next one is applied and so on. This formulation was originally discovered by Moses Schönfinkel in the 1920s but was lat…
  </blockquote>
</aside>

<p>“Gather together those things that change for the same reason, and separate those things that change for different reasons.”</p>
<ul>
<li><code>new.html</code> combines <em>for user convenience</em> entry fields with “validation error placeholders”.</li>
<li><code>UserController.new</code> uses <code>new.html</code> strictly for the entry fields.</li>
<li><code>UserController.create</code> uses <code>new.html</code> for both the entry values and validation errors.</li>
<li>Separate <code>new.html</code> and <code>create_error.html</code> views would duplicate markup and functionality. It makes sense to combine them into one <code>new.html</code>, especially as they are <em>essentially</em> coupled anyway.</li>
</ul>
<blockquote>
<p>If so (and that’s also the case), would it still be a REST violation, considering that the action is started by the controller (because the view is used indirectly for the same purpose)?</p>
</blockquote>
<ul>
<li><code>new.html</code> is the representation for <code>GET /users/new</code> (i.e. it’s an empty form)</li>
<li><code>index.html</code> is the representation for <code>GET /users</code></li>
<li>in the case of <code>create</code> (<code>POST /users</code>) <code>new.html</code> is “reused” to convey the error information - i.e .it is not a representation of any particular resource.</li>
</ul>
<blockquote>
<p>I opened this thread already thinking that since everything has to be passed explicitly as a param it probably couldn’t be achieved.</p>
</blockquote>
<p>It’s just not something that is covered out-of-the-box.</p>
<p>You are free to implement your own “Current Items” scheme - though in my personal view it’s an un-webby thing to do.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="153118" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/is-prg-a-valid-technique-in-phoenix/27249/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-153118" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="153118"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #16"></div>
  </section>
</div>
    <div class="postbit" id="153233" data-post-id="153233">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="thiagomajesk" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/thiagomajesk/120/31904_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  thiagomajesk
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/peerreynders" rel="nofollow">@peerreynders</a> Although I don’t think that my main concerns were addressed so far, there’s certainly a lot of useful information in this thread…</p>
<p>Since the reason I’ve posted was basically to see how this is being solved on the Phoenix side, I’m gonna be a little bit more practical and reformulate the question because I think if we keep expanding on other definitions we are not going to reach a conclusion.</p>
<p>By default, if the user is filling a form on <code>~/user/new</code> and there are errors on the form, because of how the routing works, the url changes to <code>~/user</code>. I see two issues here that I want to be able to solve and using PRG helps me:</p>
<ol>
<li>
<p>If the user clicks the refresh button, it shows the resubmission message which may not be desirable for UX purposes.<br>
The user might expect the page to be rebuilt instead (which is also a question posed in the “Redirect After Post” discussion and was not addressed).<br>
- There’s also the suggestion of using tokens, which does not solve the problem for other complex scenarios as described in the same discussion.</p>
</li>
<li>
<p>If the user renavigates to the current url after posting (selecting the search bar and pressing enter for example), it’ll load the <code>~/user</code> url, which shows the index page and not the form page. Then, the only way the user can start fresh in the form is pressing the backwards button - which will navigate to the previous <code>~/users/new</code> route.<br>
- This can also be counter-intuitive for mobile browsers where the forward/ backward buttons are hidden. Also, I’ve seen that some users tend not to use this feature and instead always reload the page. This combined with the fact that some devices (I guess mainly Android) have inconsistent backwards navigation, it’s a huge UX problem.<br>
- Beyond that, the problem of ‘bookmarkability’ that I think was misunderstood is not about preserving/ sharing error state, is about correctly identifying the resource (form). So in an error scenario, the user will be presented with the <code>/users</code> url instead of the right url of the page he’s at (<code>~/user/new</code>).</p>
</li>
<li>
<p>I want to separate responsibilities of building the form and actually creating it (but you pointed out that Phoenix does not work like that before. So I wonder if there are any other options).</p>
</li>
</ol>
<blockquote>
<p>It’s just not something that is covered out-of-the-box.</p>
</blockquote>
<p>I’m completely fine with that, aspnet also does not support PRG by default but there’s at least a way to transfer data on redirects (Laravel also does that).</p>
<p>Do you think that the concept of a session <a href="https://docs.microsoft.com/pt-br/aspnet/core/fundamentals/app-state?view=aspnetcore-3.0#tempdata" rel="noopener nofollow ugc">temp-data</a> that is short-lived in between redirects would break the Phoenix paradigm of doing things? Right now, I’m not sure how something similar could be achieved.</p>
<blockquote>
<p>in the case of create (POST /users) new.html is “reused” to convey the error information - i.e .it is not a representation of any particular resource</p>
</blockquote>
<p>But the route belongs to another resource. As I pointed above this can cause confusion.</p>
<blockquote>
<p>“Gather together those things that change for the same reason, and separate those things that change for different reasons.”</p>
</blockquote>
<p>I’m familiar with this definition. But it seems that this “change for the same reason” is sometimes drawn arbitrarily. So, for example: <code>UserController.new</code> beeing only responsible for building and displaying the form (with and without errors) and <code>UserController.create</code> only beeing responsible for actually posting data and redirecting is also a valid interpretation. I find difficult to argue that this does not make sense, also from the resource point of view of REST where “GET only reads and POST only writes”, but that’s not the point.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="153233" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/is-prg-a-valid-technique-in-phoenix/27249/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-153233" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="153233"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #17"></div>
  </section>
</div>
    <div class="postbit" id="153238" data-post-id="153238">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Kurisu" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Kurisu/120/14820_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Kurisu
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I just want to add that when you don’t want the default urls generated by the resources/4 macro, you could always use directly get/4 and post/4 like below:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir"># Registration
  scope "/registration", DemoWeb do
    pipe_through :browser
    get "/", RegistrationController, :new
    post "/", RegistrationController, :create
  end
</code></pre>
<p>This way the url won’t change between empty new form and create_error form. In my case I just do that for SEO purpose (for example I don’t want the url in English). And if someone shared the url, clicking on it will always result on the GET new form.</p>
<p>If you still want to redirect on invalid submit, you could assign the invalid changeset to the conn passed to redirect/2. Then you could have two clauses for your new action, one for empty form and the other for invalid form:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir"> # invalid form
  def new(%{error_changeset: changeset} = conn, _params) do
    render(conn, "new.html", changeset: changeset)
  end

  # empty form 
  def new(conn, _params) do
    changeset = Context.change_resource()
    render(conn, "new.html", changeset: changeset)
  end
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="153238" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/is-prg-a-valid-technique-in-phoenix/27249/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-153238" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="153238"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-most-liked cat-most-liked" title="One of the top 3 liked posts in this thread!"></div>
  </section>
</div>
    <div class="postbit" id="153253" data-post-id="153253">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="thiagomajesk" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/thiagomajesk/120/31904_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  thiagomajesk
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="Kurisu" data-post="19" data-topic="27249">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kurisu/48/14820_2.png" class="avatar"> Kurisu:</div>
<blockquote>
<p>If you still want to redirect on invalid submit, you could assign the invalid changeset to the conn passed to redirect/2. Then you could have two clauses for your new action, one for empty form and the other for invalid form</p>
</blockquote>
</aside>
<p>Wow! That’s a very simple solution, thanks for that <img src="https://forum.elixirforum.com/images/emoji/apple/blush.png?v=15" title=":blush:" class="emoji" alt=":blush:" loading="lazy" width="20" height="20"></p>
<p>If the <code>conn.error_changeset</code> is kept intact on a redirect, that means that I could also just assign the <code>changeset</code> variable conditionally whether or not I have errors coming through - is that right?<br>
I guess this solves the problem of sending the form state over and allows me to do a full PRG.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="153253" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/is-prg-a-valid-technique-in-phoenix/27249/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-153253" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="153253"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #19"></div>
  </section>
</div>
    <div class="postbit" id="153270" data-post-id="153270">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Kurisu" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Kurisu/120/14820_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Kurisu
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="thiagomajesk" data-post="20" data-topic="27249">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/thiagomajesk/48/31904_2.png" class="avatar"> thiagomajesk:</div>
<blockquote>
<p>If the <code>conn.error_changeset</code> is kept intact on a redirect, that means that I could also just assign the <code>changeset</code> variable conditionally whether or not I have errors coming through - is that right?</p>
</blockquote>
</aside>
<p>Yes, you can get it with something like:</p>
<p><code>changeset = conn.assigns[:error_changeset] || Context.change_resource()</code></p>
<p>So in my previous answer the matching clause would rather be</p>
<p><code>%{assigns: %{error_changeset: changeset}} = conn</code></p>
<p>If you use<code>Plug.Conn.assign/3</code> to assign the changeset it will be available in <code>conn.assigns</code>.<br>
Using a dot to access a key not present in a map will throw an error that’s why it’s better to use <code>[:key]</code> which will return nil if not found.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="153270" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/is-prg-a-valid-technique-in-phoenix/27249/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-153270" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="153270"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #20"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/27249/load_more?page=3">Load more posts</a>
</div></template></turbo-stream>