Chapters
-
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!
Encore, Symfony & API Platform
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Well hey friends! Welcome to the delightful world of Vue.js. I know I say that every topic we cover at SymfonyCasts is fun - and I totally mean that - but this tutorial is going to be a blast, as we build a rich and realistic JavaScript frontend for a store.
React vs Vue
These days, the two leaders in the frontend-framework world seem to be React and Vue.js. And just like with PHP frameworks, they're fundamentally the same: if you learn Vue.js, it'll be much easier to learn React or the other way around. If you're not sure which one to use, just pick one and run! React tends to feel a bit more like pure JavaScript while Vue has a bit more magic, which, honestly, can make it easier to learn if you're not a full-time JavaScript developer.
Vue 2 vs Vue 3
In this tutorial, we'll be using Vue version 2. But even as I'm saying this, Vue version 3 is nearing release and might already be out by the time you're watching this. But don't worry: there are actually very few differences between Vue 2 and 3 and whenever something is different, we'll highlight it in the video. So feel free to code along using Vue 2 or 3.
Project Setup
Oh, and speaking of that, to get best view of the Vue goodness - I had to get one Vue pun in - you should totally code along with me: you can download the course code from this page. After unzipping it, you'll find a start/
directory with the same code that you see here. Follow the README.md
file for all the fascinating details on how to get your project set up. The code does contain a Symfony app, but we'll spend most of our time in Vue.
One of the last steps in the README will be to find a terminal, move into the project and use Symfony's binary to start a local web server. You can download this at https://symfony.com/download. I'll say: symfony serve -d
- the -d
tells it to start in the background as a daemon - and then also --allow-http
:
symfony serve -d --allow-http
This starts a new web server at localhost:8000 and we can go to it using https
or http
. We'll talk about why I used the --allow-http
flag later.
Copy the URL, find your browser, paste it in the address bar and... say hello to a giant error!
Yarn & Webpack Encore Setup
Let's... back up. There are two things you need to know about our project. First, to help process JavaScript and CSS, we're using Webpack Encore: a simple tool to help configure Webpack. We have an entire free tutorial about it and you'll probably want to at least know the basics of Webpack or Encore before you keep going.
Our Encore config is pretty basic, with a single entry called app
. It lives in the assets/
directory - that's where all of our frontend files will live. The app.js
file doesn't actually have any JavaScript, but it does load an app.scss
file that holds some basic CSS for our site, including Bootstrap. Our base layout already has a link
tag to the built app.css
file... which exploded because we haven't executed Encore and built those assets yet.
Back at your terminal, start by installing Encore and our other Node dependencies by running:
yarn install
If you don't have node
or yarn
installed, head to https://nodejs.org and https://yarnpkg.io to get them. You can also use npm
if you want. Once this is done populating our node_modules/
directory, we can run Encore with:
yarn watch
This builds the assets into the public/build
directory and then waits and watches for more changes: any time we modify a CSS or JS file, it will automatically re-build things. The watch
command works thanks to a section in my package.json
file: watch
is a shortcut for encore dev --watch
.
Ok! Let's try the site again - refresh! Welcome to MVP Office Supplies! Our newest lean startup idea here at SymfonyCasts. Ya see, most startups take a lot of shortcuts to create their first minimum viable product. We thought: why not take that same approach to office furniture and supplies? Yep, MVP Office Supplies is all about delivering low-quality - "kind of" functional - products to startups that want to embody the minimum-viable approach in all parts of their business.
Traditional Symfony App Mixed with Vue
Everything you see here is a traditional Symfony app: there is no JavaScript running on this page at all. The controller lives at src/Controller/ProductController.php
: index()
is the homepage and it renders a Twig template: templates/product/index.html.twig
. Here's the text we're seeing.
The point is: right now, this is a good, traditional, boring server-side-generated page.
API Platform API
The second important thing about our app is that it already has a really nice API. You can see its docs if you go to https://localhost:8000/api. We built this with my favorite API tool: API Platform. We have several tutorials on SymfonyCasts about it.
Inside our app - let me close a few files - we have 6 entities, or database tables: Product
, Category
and a few others we won't worry about in this tutorial. Each of these has a series of API endpoints that we will call from Vue.
For example, back on the browser, scroll down to the Product
section: we can use these interactive docs to try an endpoint: let's test that if you make a request to /api/products
, that will return a JSON collection of products. Hit Execute and... there it is! This funny-looking JSON format is called JSON-LD, it's not important for Vue - it's basically JSON with extra metadata. Under the hydra:member
property, we see the products: a useful Floppy disk and some blank CD's - all kinds of great things for a startup in the 21st century.
We'll be using this API throughout the tutorial.
Ok, click back to the homepage. Next, let's get Vue installed, bootstrap our first Vue instance and see what this puppy can do!
48 Comments
Hi team!
Little problem while installing the project.
Running yarn watch
results in
yarn run v1.22.19
$ encore dev --watch
Running webpack ...
webpack is watching the files…
node:internal/crypto/hash:69
this[kHandle] = new _Hash(algorithm, xofLen);
^
Error: error:0308010C:digital envelope routines::unsupported
at new Hash (node:internal/crypto/hash:69:19)
at Object.createHash (node:crypto:133:10)
at module.exports (/home/xxxx/PhpstormProjects/code-vue/start/node_modules/webpack/lib/util/createHash.js:135:53)
at NormalModule._initBuildHash (/home/xxxx/PhpstormProjects/code-vue/start/node_modules/webpack/lib/NormalModule.js:417:16)
at handleParseError (/home/xxxx/PhpstormProjects/code-vue/start/node_modules/webpack/lib/NormalModule.js:471:10)
at /home/xxxx/PhpstormProjects/code-vue/start/node_modules/webpack/lib/NormalModule.js:503:5
at /home/xxxx/PhpstormProjects/code-vue/start/node_modules/webpack/lib/NormalModule.js:358:12
at /home/xxxx/PhpstormProjects/code-vue/start/node_modules/loader-runner/lib/LoaderRunner.js:373:3
at iterateNormalLoaders (/home/xxxx/PhpstormProjects/code-vue/start/node_modules/loader-runner/lib/LoaderRunner.js:214:10)
at Array.<anonymous> (/home/xxxx/PhpstormProjects/code-vue/start/node_modules/loader-runner/lib/LoaderRunner.js:205:4)
at Storage.finished (/home/xxxx/PhpstormProjects/code-vue/start/node_modules/webpack/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:55:16)
at /home/xxxx/PhpstormProjects/code-vue/start/node_modules/webpack/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:91:9
at /home/xxxx/PhpstormProjects/code-vue/start/node_modules/graceful-fs/graceful-fs.js:123:16
at FSReqCallback.readFileAfterClose [as oncomplete] (node:internal/fs/read_file_context:68:3) {
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'
}
Node.js v18.17.0
error Command failed with exit code 1.
Any idea about how to solve this and running the project ?
Thanks
Fixed by updating the package.json
{
"browserslist": [
"defaults"
],
"devDependencies": {
"@symfony/webpack-encore": "^0.30.0",
"bootstrap": "^4.4.1",
"core-js": "^3.0.0",
"eslint": "^6.7.2",
"eslint-config-airbnb-base": "^14.0.0",
"eslint-plugin-import": "^2.19.1",
"eslint-plugin-vue": "^6.0.1",
"regenerator-runtime": "^0.13.2",
"sass": "^1.29.0",
"sass-loader": "^8.0.0",
"webpack-notifier": "^1.6.0"
},
"license": "UNLICENSED",
"private": true,
"scripts": {
"dev-server": "NODE_OPTIONS=--openssl-legacy-provider encore dev-server",
"dev": "NODE_OPTIONS=--openssl-legacy-provider encore dev",
"watch": "NODE_OPTIONS=--openssl-legacy-provider encore dev --watch",
"build": "encore production --progress",
"lint": "node_modules/.bin/eslint assets/** --ignore-pattern *.scss --ignore-pattern *.gif --ignore-pattern *.png"
}
}
Hey @atournayre,
Thanks for sharing your solution. That issue is a headache, especially with software which has lot of updates.
Cheers!
Hello,
Thank you first of all, i m having an issue with start project.
vendors.js:5863 You are currently using minified code outside of NODE_ENV === "production". This means that you are running a slower development build of Redux. You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify or setting mode to production in webpack (https://webpack.js.org/concepts/mode/) to ensure you have the correct code for your production build.
Hey Msthzn,
Hm, did you download the course and and started from start/ directory? Did you run all the instructions from the README.md file inside? What exactly command are you running when seeing this error? Because I just ran "yarn install" and "yarn watch" and didn't see this error. Btw, it feels like a warning, so probably you can just ignore it if that's just your learning project.
Cheers!
Hi!
Can I use this repository instead of start directory provided in this tutorial?
https://github.com/SymfonyC...
Followed 25 episodes. So far no problems yet.
Hey Ruslan I.!
You already answered your own question, but yes, absolutely. The "start" code is identical to that. However, for Vue part 2, that won't be the case. The starting code for that is only available by downloading from the site (which is for subscribers). You CAN use the "finish" code from what you did on Vue 1... but sometimes we upgrade and tweak a few things between tutorials (I try to minimize that, but it's unavoidable to a point).
Cheers!
Hey, it is wonderful that Symfony and SymfonyCasts stand in solidarity with the people of Ukraine. Respectfully, I think it would also be great if you were to declare your solidarity with all the other victims of military aggression around the world in modern history -- not least notably, the millions of innocent civilians displaced, wounded or slaughtered in wars waged by the United States in places like Iraq and Afghanistan.
Hey davidmintz!
Thanks for the thoughtful message. I think war sucks in any context. The cost to innocent civilians is real, and horrible and huge. At the end of the day, we can't comment on every conflict or issue. However, *this* war is directly affecting a member of our team.
If you'd like to discuss further, I'd appreciate an email to ryan@symfonycasts.com - just so we can keep the conversation below the videos technically relevant.
Cheers!
I hear you. Also horrified that a member of your team is in the middle of it, and fervently hoping he comes out of it ok.
Hello,
If we compare Symfony with any PHP framework , it's look like compare Mercedes S-class with other car. Symfony the best or nothing! Buuut if we speak about Vue and React? What is Front-End "Mercedes" ? What you prefer or maybe there are some props ? Why i am asking because at SymfonyCast have 2 options. However Symfony Core Team have a mountain :) and could see bigger picture in future...... Thanks for reply
Hi, Maxim!
That is a very tough question to answer, as the front-end situation is not as stable as back-end where Symfony clearly dominates. Even as close as a few months ago, I would definitely answer with ReactJS or VueJS. Any of those frameworks are equally powerful and it really depends on personal choice as to what route to go for a project! But with the recent news about Symfony-ux, StimulusJS and Turbo, the entire universe seems to be shaken. I would definitely say that Stimulus + Turbo is the future of front-end, at least for Symfony projects, because this seems to be *just* what Symfony needs! (Go take a look at our Stimulus and Turbo tutorials if you whish! They are really good!)
Agh! So many (great) choices.
I have been writing Javascript since about 1998, and trust me: it's not an advantage. I adopted jQuery and jQuery-ui some years ago, stayed there for years, and it's taken me till about now to start advancing into the modern age -- and it's really fun to be learning this. Oh my, Javascript, how you've grown!
Hi David!
The JavaScript ecosystem has indeed grown and matured A LOT during the past 6 or so years. It's quite remarkable! I'm glad you find this useful! I think you will love the stimulus/turbo tutorials as well!
For setting up the project, I can't get past creating the database. It says No Driver Found. I have Mysql v 5.7 running and have the .env file set to use my mysql username and password. Is there anything else it's looking for that I'm missing? I did what was suggested in another post, creating a new user and giving it full privileges.
Hey Karl C.
Double check your database URI is set correct in your .env
file and that you don't have a .env.local
overriding it. Another thing to check is the database server is running and you have the PHP PDO module configured
Cheers!
Thanks. The line for pdo_mysql was commented out in the php.ini. Works now.
Thought I posted about some errors I was getting out of the box on this. Has this been tested as of late? At least one of the errors I'm getting seems to be some sort of Doctrine issue. I'm using Docker for the database otherwise it's strictly following the course code install.
Hey @Aaron!
Ah, yup! There is an issue! I've been mucking around lately on some of our tutorials upgrading the dependencies a little bit so that the code would work on PHP 8. Apparently (I just discovered the same issue on a different tutorial), I ended up with a bad combination of SensioFramworkExtraBundle and Doctrine. I'm going to get this fixed up ASAP.
In the mean time, here is the fix:
compose up sensio/framework-extra-bundle doctrine/migrations
(the doctrine/migrations upgrade is only needed if you're using PHP 8 + MySQL, so I mentioned it to be safe).
Cheers!
Anyone having issues with the start project when running php 8? Composer install was saying it requires php ^7.2.9 but my version (8/0/2) doesn't satisfy that requirement. If I update the composer.json to require ^7.2.9|^8.0 and do a composer update I get a fail on doctrine/inflector 1.3.* requires php ^7.1.
I've updated then updated it so that it is looking for doctrine/inflector ^1.3, the composer update then runs but when it calls the script cache:clear I get:
Script cache:clear returned with error code 255<br />!!<br />!! Warning: Uncaught ReflectionException: Class "Doctrine\Common\Persistence\ObjectManager" not found while loading "App\DataFixtures\AppFixtures". in /Users/chrisl/Development/PHP/symfony/code-vue/start/vendor/composer/ClassLoader.php:444<br />
a load of stack traces and then<br />!! Fatal error: Could not check compatibility between App\DataFixtures\AppFixtures::load(Doctrine\Common\Persistence\ObjectManager $manager) and Doctrine\Common\DataFixtures\FixtureInterface::load(Doctrine\Persistence\ObjectManager $manager), because class Doctrine\Common\Persistence\ObjectManager is not available in /Users/chrisl/Development/PHP/symfony/code-vue/start/src/DataFixtures/AppFixtures.php on line 14<br />
Have searched google but am struggling to find a solution to this - anyone have any suggestions?
Hey Chris L.!
Give me a little time to check into this. Historically, we have purposely fixed our code downloads at the lowest PHP version that we support - so 7.2.9 for this tutorial. That prevents Composer from downloading dependencies that might only work on higher versions (e.g. 7.3 or 8.0), which would make the tutorial not work for users on 7.2. The idea is to get the tutorial code to work for as many people as reasonably possible.
But, PHP 8 is an extra challenge :P. If we tell Composer to use PHP 7.2 when downloading the dependencies, it's highly likely (almost guaranteed) that some dependencies will be downloaded that work on PHP 7.X, but do not work on PHP 8.0. I need to think about the best way we might solve this.
However, even though it's more work than I'd want you to have to do, you're absolutely on the right track with updating the dependencies. For the specific Doctrine\Common\Persistence\ObjectManager
issue, change the use statement in AppFixtures to Doctrine\Persistence\ObjectManager
. There may be other changes you need to make, but that will hopefully take care of that one ;).
Cheers!
Thanks - that did indeed fix that issue but ended up with some others. What I am going to try instead is creating a blank project, adding in the required packages via composer and then copying across the code into my project to see if I can get it working that way.
Thanks once again for your help, hopefully I'll manage to get this lot working as the course looks really good.
Hey Chris!
That’s sounds like a good plan - I can’t think of anything in the code (that you’ll be copying over) that would need adjustment with slightly newer dependencies.
If you do hit any issues, let me know.
Cheers!
Could a script be provided to create tables for this project, please?
The commands
php bin/console doctrine:database:create
php bin/console doctrine:migrations:migrate
php bin/console doctrine:fixtures:load
don't work for me.
Thanks.
Hey AbelardoLG,
Hm, try these steps:
php bin/console doctrine:database:create
php bin/console doctrine:schema:create
php bin/console doctrine:fixtures:load
I.e. use "doctrine:schema:create" instead of the migration, most probably the migration is not complete on your local setup or you messed up with some migrations
Cheers!
The issue here comes from my last question you gently replied.
Cheers.
Hey AbelardoLG,
Ah, great! I'm glad it's not a problem for you anymore :)
Cheers!
Hi,
Again the same problem here.
I created an user root inside my local mysql installation. I set for it a password as it is mandatory.
When I run the php bin/console doctrine:database:create command, it displays the classical message:
An exception occurred in driver: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: NO)
DATABASE_URL=mysql://root:CY$Fzw10Am@127.0.0.1:3306/vue_course?serverVersion=8.0
I created a new user 'symfony' with the same password but same happens. What's wrong?
Any idea to solve this issue, please? Thanks in advance. Brs.
Hey AbelardoLG,
Yeah, in latest major MySQL version there're some problems with root user to access the DB from PHP script. So, the easiest solution is to create a new user like you did, e.g. call it "symfony". But you have to grant all the required permissions to that new user! Please, make sure that user has permissions to create databases, etc. You can find a lot of useful resource on the internet how to do it properly. Also, use "mysql" command in your terminal to check the credentials. You can access the MySQL with the new credentials - then you should have access from the PHP script as well using valid credentials
As an alternative solution - you can consider using Docker to spin up your MySQL server in a container and expose it to your local machine.
Cheers!
Yes, I granted all permissions to "symfony".
And yes, I will use Docker in order to eliminate any headache.
Thanks for your pieces of advice, Victor. :) Best regards.
Hey AbelardoLG,
Ah, ok... I probably know the problem you have... From the DATABASE_URL you showed above I can suppose that you may have problems with the password as it contains some extra chars, most likely "$" causes this problem. Try to set a simple password with numbers and letters only, i.e. without any extra chars, e.g. "CYFzw10Am" and try again - this should work. The special chars should be probably avoided or escaped properly, easier to avoid them for the passwords you set via env variables :)
Cheers!
HOORAY!
That was the reason of my headache!
Bigtor! ;)
Haha, awesome :)
Cheers!
Hi Guys,
Great tutorial.
But upon adding the data from the API, I was failing.
It turns out I missed the instruction to install the database.
Luckily I do understand Symfony, so I managed.
But perhaps you could add this?
Or have I overlooked it and missed it somehow?
Sjoerd
Hey Sjoerd!
Thanks for the note - sometimes we DO miss things like this :). We don't actually show the setup in the tutorial, but in the first chapter - https://symfonycasts.com/sc... - we mention that you should follow the README.md file in the code download to get things working. You might have just not seen that? Or was it not obvious (or was the README missing details)?
Cheers!
Hi Ryan.
I actually did find the README.md you are referring to. It is in the "finish" folder rather than the "start" folder, which I used during the tutorial.
I guess I expected it to be in start, never looked any further.
Keep up the great tutorials!
Have a great day!
Hey Sjoerd!
> I actually did find the README.md you are referring to.
Excellent!
> It is in the "finish" folder rather than the "start" folder, which I used during the tutorial.
> I guess I expected it to be in start, never looked any further.
Hmm, it should also be in the start/ directory - that's actually the MOST important spot. I just double-checked the code download, and it does appear to be there... so how knows :). Anyways, it looks like all is good now. Thanks again for reporting any potential "weirdness" that you see!
Cheers!
Thank you alot for this tutorial, I think it would be nice if there was a data validation section on the client side and server .
Thank you for your kind words, Monia! Stay tuned for part 2 of this tutorial where, at the end, we show just that! :)
Thanks for bring us this course. I'd like know where Node.js will be used in this tutorial ?
Hi Gilson!
We use NodeJS under the hood in this tutorial as the technology upon which Webpack and Encore work. We also use Yarn (although npm can be used as well) as our package manager for downloading and maintaining the packages needed in the application.
Being this a Vue tutorial (where we focus on the front end in an application written in Symfony), we won't be using NodeJS to render pages server side or writing scripts ourselves.
I hope this helps clarify your question!
Hi, I was waiting so long for this course :)
Thank you so much i love symfony + encore + vue.
But i have a little problem.
I'm using typescript and when I compile and in my editor I'm getting error that "in my vue components it can't find some depencies".
here is what I did,
<b>tsconfig:</b>
"include": [
"assets/**/*.ts",
"assets/**/*.tsx",
"assets/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
<b>webpack.config.js:</b>
// This is our alias to the root vue components dir
.addAliases({
"@": path.resolve(__dirname, "assets/js"),
styles: path.resolve(__dirname, "assets/scss"),
vue_app: path.resolve(__dirname, "assets/vue"),
})
and my vue components are located in: "./assets/vue/views/..."
i'm getting this error:
ERROR Failed to compile with 98 errors
error in ./assets/vue/models/Application.ts
[tsl] ERROR in ./assets/vue/models/Application.ts(1,23)
TS2307: Cannot find module 'vue_app/entities/Container'.
Sory i know it's out of this course scope, but it can be fun to add so vue typescript topics.
:)
Hi Moulaye!
It seems you've forgotten to include your webpack aliases to the TypeScript tsconfig file. You can find documentation here:
<a href="https://www.typescriptlang.org/tsconfig#paths" target="_blank">https://www.typescriptlang.org/tsconfig#paths</a>
A good example of what you need to do would be:
{
"baseUrl": "./assets",
"paths": {
"@": ["js"],
"vue_app": ["assets/vue"]
}
}
Hope this helps!
"Houston: no signs of life"
Start the conversation!
What JavaScript libraries does this tutorial use?
// package.json
{
"devDependencies": {
"@symfony/webpack-encore": "^0.30.0", // 0.30.2
"axios": "^0.19.2", // 0.19.2
"bootstrap": "^4.4.1", // 4.5.0
"core-js": "^3.0.0", // 3.6.5
"eslint": "^6.7.2", // 6.8.0
"eslint-config-airbnb-base": "^14.0.0", // 14.1.0
"eslint-plugin-import": "^2.19.1", // 2.20.2
"eslint-plugin-vue": "^6.0.1", // 6.2.2
"regenerator-runtime": "^0.13.2", // 0.13.5
"sass": "^1.29.0", // 1.29.0
"sass-loader": "^8.0.0", // 8.0.2
"vue": "^2.6.11", // 2.6.11
"vue-loader": "^15.9.1", // 15.9.2
"vue-template-compiler": "^2.6.11", // 2.6.11
"webpack-notifier": "^1.6.0" // 1.8.0
}
}
Just looking through your Product inventory -- OMG you guys are truly funny. This is great <3