Chapters
57 Chapters
|
6:19:46
|
Login to bookmark this video
-
Course Code
Subscribe to download the code!
Subscribe to download the code!
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
37.
Redirecting the Full Page from a Frame
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Subscribe to jump to this part in the video!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": ">=8.2",
"ext-ctype": "*",
"ext-iconv": "*",
"composer/package-versions-deprecated": "1.11.99.1", // 1.11.99.1
"doctrine/annotations": "^1.0", // 1.13.1
"doctrine/doctrine-bundle": "^2.2", // 2.3.2
"doctrine/orm": "^2.8", // 2.9.1
"phpdocumentor/reflection-docblock": "^5.2", // 5.2.2
"sensio/framework-extra-bundle": "^6.1", // v6.1.4
"symfony/asset": "5.3.*", // v5.3.0-RC1
"symfony/console": "5.3.*", // v5.3.0-RC1
"symfony/dotenv": "5.3.*", // v5.3.0-RC1
"symfony/flex": "^1.3.1", // v1.21.6
"symfony/form": "5.3.*", // v5.3.0-RC1
"symfony/framework-bundle": "5.3.*", // v5.3.0-RC1
"symfony/property-access": "5.3.*", // v5.3.0-RC1
"symfony/property-info": "5.3.*", // v5.3.0-RC1
"symfony/proxy-manager-bridge": "5.3.*", // v5.3.0-RC1
"symfony/runtime": "5.3.*", // v5.3.0-RC1
"symfony/security-bundle": "5.3.*", // v5.3.0-RC1
"symfony/serializer": "5.3.*", // v5.3.0-RC1
"symfony/twig-bundle": "5.3.*", // v5.3.0-RC1
"symfony/ux-chartjs": "^1.1", // v1.3.0
"symfony/ux-turbo": "^1.3", // v1.3.0
"symfony/ux-turbo-mercure": "^1.3", // v1.3.0
"symfony/validator": "5.3.*", // v5.3.0-RC1
"symfony/webpack-encore-bundle": "^1.9", // v1.11.2
"symfony/yaml": "5.3.*", // v5.3.0-RC1
"twig/extra-bundle": "^2.12|^3.0", // v3.3.1
"twig/intl-extra": "^3.2", // v3.3.0
"twig/string-extra": "^3.3", // v3.3.1
"twig/twig": "^2.12|^3.0" // v3.3.2
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.0
"symfony/debug-bundle": "^5.2", // v5.3.0-RC1
"symfony/maker-bundle": "^1.27", // v1.31.1
"symfony/monolog-bundle": "^3.0", // v3.7.0
"symfony/stopwatch": "^5.2", // v5.3.0-RC1
"symfony/var-dumper": "^5.2", // v5.3.0-RC1
"symfony/web-profiler-bundle": "^5.2", // v5.3.0-RC1
"zenstruck/foundry": "^1.10" // v1.10.0
}
}
What JavaScript libraries does this tutorial use?
// package.json
{
"devDependencies": {
"@babel/preset-react": "^7.0.0", // 7.13.13
"@fortawesome/fontawesome-free": "^5.15.3", // 5.15.3
"@hotwired/turbo": "^7.0.0-beta.5", // 1.2.6
"@popperjs/core": "^2.9.1", // 2.9.2
"@symfony/stimulus-bridge": "^2.0.0", // 2.1.0
"@symfony/ux-chartjs": "file:vendor/symfony/ux-chartjs/Resources/assets", // 1.1.0
"@symfony/ux-turbo": "file:vendor/symfony/ux-turbo/Resources/assets", // 0.1.0
"@symfony/ux-turbo-mercure": "file:vendor/symfony/ux-turbo-mercure/Resources/assets", // 0.1.0
"@symfony/webpack-encore": "^1.0.0", // 1.3.0
"bootstrap": "^5.0.0-beta2", // 5.0.1
"chart.js": "^2.9.4",
"core-js": "^3.0.0", // 3.13.0
"jquery": "^3.6.0", // 3.6.0
"react": "^17.0.1", // 17.0.2
"react-dom": "^17.0.1", // 17.0.2
"regenerator-runtime": "^0.13.2", // 0.13.7
"stimulus": "^2.0.0", // 2.0.0
"stimulus-autocomplete": "https://github.com/weaverryan/stimulus-autocomplete#toggle-event-always-dist", // 2.0.0
"stimulus-use": "^0.24.0-1", // 0.24.0-2
"sweetalert2": "^11.0.8", // 11.0.12
"webpack-bundle-analyzer": "^4.4.0", // 4.4.2
"webpack-notifier": "^1.6.0" // 1.13.0
}
}
9 Comments
Hi, I am sorry if I missed something, but I have taken this course to figure out how to make advanced dialogs using Turbo and Stimulus with Symfony. The solution in the tutorial looks fine, but I have noticed two things.
First, after successfully submitting the form, the server will give you a response with the HTML of the page you are supposed to be redirected. This response contains new data which has been submitted in the form.
Second, if you put any flash messages after the form submission, the messages won't show up because the first response from the first reason is ignored. This response just serves to check if the form is submitted successfully or not.
So, I need help with Turbo to figure out if is there any way to avoid using Turbo visit but try to use the HTML response that the server gives you after the form is submitted and successfully validated. This will be much better because the data on the website will be automatically updated, flash messages will be visible, and the front end doesn't need to fetch any extra data because everything is already delivered as a response immediately after submission.
Hey @Karloci!
I might have a simple answer for you :). Have you checked out the modal system we created for the LAST stack tutorial? https://symfonycasts.com/screencast/last-stack It's a bit more recent, and I really tried to solve all of the issues there. This includes rendering the flash messages on success and updating the current page (through Turbo streams).
However, I do think you still have a nice question:
This is interesting. What you're basically wanting is for the
<form>in the modal to submit via a turbo-frame and load into the turbo frame if the validation fails. But as soon as validation is successful and you redirect, make this work like a real, full-page Turbo navigation. You're not alone to ask about this :) https://github.com/hotwired/turbo/issues/138There are a bunch of workaround there. The simplest is to add an event listener that sees the 200 status code, then does a
Turbo.visit()to the new URL. The problem is that, in reality, the target page is rendered twice: once on the form submit / redirect, then again with theTurbo.visit(). Unfortunately, it is that SECOND request that you ultimately render... and it will be missing the flash messages because they were rendered on the first request (whose response is ignored).So my favorite work-around is this "flavor": https://github.com/hotwired/turbo/issues/138#issuecomment-1032866471
Basically, you stop using a
turbo-frameand, on submit with an error, return a turbo-stream that updates the modal element. On successful submit, you redirect.I wish there were a better solution where Turbo could just "use" the HTML from the initial redirect, bit it's not possible (and I half understand the technical reasons in Turbo why).
Cheers!
Hey !
I've been struggling with this problem for a full day, spending time first to understand why my flashes weren't displayed. After figuring out, I found this post.
I don't really like the idea to stop using the frame in the modal which is really convenient.
So I figured out another workaround. When redirecting I also add a flash called
_redirect. Then in my modal template I render flashes only if the request is from the modal frame AND if the _redirect flashbag is empty. Moreover, in my base template I render flashes only if the request is not from a modal frame.The cool part is that the
_redirectflashbag is cleaned up just by checking if it's not empty. And then on the next page flashes will be rendered correctly.The counterpart is to use addFlash before every redirect, it can be automated by creating a service or even overriding the default redirectToRoute function maybe ?
Controller :
Modal flash rendering :
(notice that
app.flashes('_redirect')comes first in the if statement to process it in any cases, beacause if checking firstapp.request.headers.get('turbo-frame') == 'modal'and it's returned false, it would not process the second part of the AND)base template :
Hey Hugo,
That's an interesting workaround, thanks for sharing it with others!
Cheers!
I'm sorry, I did not completly understand, how is the turbo-helper instantiated? Does/should it happen automatically, oder do i have to create it from within app.js manually?
Hey @Ole!
No worries :). It IS imported from
app.js- we did it WAY back on chapter 11 - https://symfonycasts.com/screencast/turbo/organize#codeblock-b154ca5114Let me know if that helps!
Cheers!
Thanks for the quick reply :-)
Well, OK, importing the js file seems to be enough, at least beforeFetchResponse is called now. But I have one more problem now:
Altough beforeFetchResponse is called, it is only called for the second request, which is already redirected. It is never called for the first redirect response (Status Code 302/303).
Is this the expected behaviour? Seems a little bit irritating to me.
Also, the second requests generate an exception:
`Twig\Error\LoaderError:
Unable to find template "default/default.turbo_stream.twig"`
(while calling that URL directly in the browser renders just fine using an completly different template).
Sorry, if this sounds a bit confusing.
Well, this works for me now, I'm not sure what caused this, maybe it was an cache issue? I also added an empty "templates/default/default.turbo_stream.twig" file to the project tree. Anyway, thanks for your support :-)!
Yea, sometimes the cache is the problem. When I'm not sure if the my browser downloaded the most recent assets I just do a hard refresh
Cheers!
"Houston: no signs of life"
Start the conversation!