WEBVTT

NOTE Created by CaptionSync from Automatic Sync Technologies www.automaticsync.com

00:00:03.636 --> 00:00:08.256 align:middle
Open Components/RepLogApp.js
and search for Routing.

00:00:09.046 --> 00:00:09.606 align:middle
Guess what?

00:00:10.206 --> 00:00:13.946 align:middle
This Routing variable is a global variable.

00:00:14.446 --> 00:00:17.186 align:middle
Boo! It's our last one.

00:00:18.146 --> 00:00:20.126 align:middle
In templates/, open the base layout.

00:00:21.036 --> 00:00:27.066 align:middle
Other than a polyfill - which we won't talk
about - there are only two script tags left.

00:00:27.066 --> 00:00:34.176 align:middle
These give us the Router variable and they come
from FOSJsRoutingBundle: a really cool bundle

00:00:34.306 --> 00:00:38.686 align:middle
that allows you to generate URLs
from Symfony routes in JavaScript.

00:00:39.746 --> 00:00:46.436 align:middle
Our goal is clear: refactor our code so
that we can require the Router instead

00:00:46.436 --> 00:00:48.156 align:middle
of relying on the global variable.

00:00:49.196 --> 00:00:54.206 align:middle
The first interesting thing is
that this is not a Node package.

00:00:55.076 --> 00:01:01.626 align:middle
Nope, it's a normal PHP package that
happens to have a JavaScript file inside.

00:01:02.056 --> 00:01:04.546 align:middle
But, that doesn't really make any difference...

00:01:04.686 --> 00:01:09.256 align:middle
except that the path for it is ugly: it lives

00:01:09.256 --> 00:01:17.036 align:middle
in vendor/friendsofsymfony/jsrouting-bundle
/Resources/public/js/router.js.

00:01:18.026 --> 00:01:27.086 align:middle
Wow! Ok then: const Routing = require(), then
go up a few directories and follow the path:

00:01:27.086 --> 00:01:34.216 align:middle
vendor/friendsofsymfony/jsrouting-bundle
/Resources/public/js/router.js.

00:01:35.396 --> 00:01:37.286 align:middle
Simple enough!

00:01:37.286 --> 00:01:38.606 align:middle
Let's try it!

00:01:39.936 --> 00:01:41.986 align:middle
In your browser, refresh!

00:01:44.176 --> 00:01:45.916 align:middle
Bah! Error!

00:01:46.416 --> 00:01:51.116 align:middle
The route rep_log_list does not exist Booo!

00:01:51.676 --> 00:01:54.926 align:middle
This error comes from inside the Router.

00:01:55.616 --> 00:02:00.866 align:middle
Here's what's going on: this JavaScript
library is more complex than most.

00:02:01.476 --> 00:02:05.096 align:middle
The first script tag gives
us the Router variable.

00:02:05.606 --> 00:02:12.816 align:middle
But the second executes a dynamic endpoint that
fetches a JSON list of the route information

00:02:13.096 --> 00:02:15.366 align:middle
and then sets that on the router.

00:02:16.296 --> 00:02:18.576 align:middle
When we simply require the router...

00:02:18.896 --> 00:02:20.996 align:middle
we do get the Router object...

00:02:21.316 --> 00:02:23.516 align:middle
but it has no routes!

00:02:24.206 --> 00:02:28.136 align:middle
So the question is: how can
we get the dynamic route info

00:02:28.136 --> 00:02:30.966 align:middle
so that it can be set into the router?

00:02:32.076 --> 00:02:34.616 align:middle
Actually, this is possible!

00:02:34.616 --> 00:02:39.916 align:middle
If you look at the Usage section of
the bundle's docs, it talks about how

00:02:39.916 --> 00:02:41.936 align:middle
to integrate with Webpack Encore.

00:02:43.356 --> 00:02:46.116 align:middle
Basically, by running a bin/console command,

00:02:46.416 --> 00:02:50.576 align:middle
you can dump your route information
to a static JSON file.

00:02:51.176 --> 00:02:56.356 align:middle
Then, you can require that JSON from
Webpack and set it on the Router.

00:02:57.026 --> 00:03:01.656 align:middle
Oh, and don't worry about this import
syntax - it's basically the same

00:03:01.656 --> 00:03:04.066 align:middle
as require, and we'll talk about it next.

00:03:04.936 --> 00:03:06.426 align:middle
So this is really cool!

00:03:06.836 --> 00:03:11.306 align:middle
It shows how you can even require
JSON files from JavaScript!

00:03:11.716 --> 00:03:19.066 align:middle
But... it has a downside: each time you add
a new route, you need to re-run the command.

00:03:19.706 --> 00:03:22.216 align:middle
That can be a pain during development.

00:03:23.136 --> 00:03:29.626 align:middle
It's still a great option - and is a bit faster
on production - but it does have that weakness.

00:03:30.826 --> 00:03:32.586 align:middle
And there is another option.

00:03:33.086 --> 00:03:35.456 align:middle
It's not quite as fancy or awesome...

00:03:35.456 --> 00:03:36.486 align:middle
but it's easier.

00:03:37.326 --> 00:03:42.386 align:middle
Inside assets/js/Components, create
a new file called Routing.js.

00:03:43.956 --> 00:03:49.606 align:middle
Inside, um, just say, module.exports
= window.Routing.

00:03:51.076 --> 00:03:54.976 align:middle
Yep! We are going to continue
using the global variable.

00:03:55.476 --> 00:04:01.466 align:middle
But now, we can at least require
this file from everywhere else

00:04:01.516 --> 00:04:06.886 align:middle
so that our code looks more
responsible: const Routing = require('.

00:04:07.146 --> 00:04:08.136 align:middle
/Routing').

00:04:09.536 --> 00:04:14.056 align:middle
And now, when we refresh, it works.

00:04:14.816 --> 00:04:19.406 align:middle
The cool thing about this hacky
solution is that if you want to change

00:04:19.406 --> 00:04:22.486 align:middle
to the better solution later, it's easy!

00:04:23.046 --> 00:04:28.196 align:middle
Just put the correct code in Router.js,
and everything will already be using it.

00:04:28.976 --> 00:04:29.506 align:middle
Nice!

