Modernizing with fetch() and await
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.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeThis chapter isn't related to upgrading Symfony. But the rest of our code - including JavaScript - deserves to be modernized too!
Using fetch() instead of axios
Inside song-controls_controller.js, I originally used axios to make Ajax calls.
| // ... lines 1 - 11 | |
| import axios from 'axios'; | |
| // ... line 13 | |
| export default class extends Controller { | |
| // ... lines 15 - 18 | |
| play(event) { | |
| // ... lines 20 - 21 | |
| axios.get(this.infoUrlValue) | |
| // ... lines 23 - 26 | |
| } | |
| } |
I don't do that anymore. Instead, use the built-in fetch() function.
Remove axios with:
php bin/console importmap:remove axios
It's gone from importmap.php. Then delete the import... and this comment while we're here. Replace axios.get() with just fetch(). Then, to see if this is working, console.log(response).
| // ... lines 1 - 2 | |
| export default class extends Controller { | |
| // ... lines 4 - 7 | |
| play(event) { | |
| // ... lines 9 - 10 | |
| fetch(this.infoUrlValue) | |
| .then((response) => { | |
| console.log(response); | |
| const audio = new Audio(response.data.url); | |
| audio.play(); | |
| }); | |
| } | |
| } |
Over in browser-land, smash that play button to trigger the method. Cool! The last two lines aren't working, but we see the response! It did make an Ajax call.
When I originally wrote this, I used .then() to handle the Promise. I don't often use that anymore to handle asynchronous code. Instead, I use the simpler await.
Using await & async
In front of fetch, say const response = await fetch(). Then copy the inside of the callback and put it right after.
| // ... lines 1 - 2 | |
| export default class extends Controller { | |
| // ... lines 4 - 7 | |
| async play(event) { | |
| // ... lines 9 - 10 | |
| const response = await fetch(this.infoUrlValue); | |
| console.log(response); | |
| //const audio = new Audio(response.data.url); | |
| //audio.play(); | |
| } | |
| } |
This says: make the fetch() call, wait for it to finish, and then run this code. It's much simpler to read and write.
Though, you probably noticed my angry editor:
the await operator can only be used in an async function.
To use await, we need to add async before the function that we're directly inside. I won't go into the details, but this advertises that our function is now asynchronous. If you called it and wanted the return value, you'd need to await that call as well.
But in our case, Stimulus is calling this method... and it definitely does not care about our return value. So adding async doesn't change anything.
When we try it... the same result, without the callback.
So let's finish this: const data = await response.json().
This takes the JSON from the response of our API endpoint and converts it into an object. And yea, it's also an asynchronous function, so await comes in handy again! Below, pass data.url to Audio.
| // ... lines 1 - 2 | |
| export default class extends Controller { | |
| // ... lines 4 - 7 | |
| async play(event) { | |
| event.preventDefault(); | |
| const response = await fetch(this.infoUrlValue); | |
| const data = await response.json(); | |
| const audio = new Audio(data.url); | |
| audio.play(); | |
| } | |
| } |
Then celebrate, that sweet, sweet Rickroll. Modern code, no build system: life is good.
Now that we're upgraded, let's take a tour into some of my favorite new features, starting with autowiring goodies that might mean you'll never edit services.yaml again.
4 Comments
How dare you Rick Roll me Ryan !!!! Ahahhaha JK thanks for yet an amazing tutorial <3 <3 <3
Hey @stlgaits ,
Whoops, haha :) Thanks for your nice feedback ;)
Stay tuned for more tunes :p
Cheers!
I hope this amazing tutorial, may include a video about how to setup symfony/ux-react using typescript components.
🤞🤞
Sorry @john-erney-rojas :). React/Vue/etc just isn't something I'm into much right now. Nothing wrong with them - but I much prefer the approaches in LAST stack - https://symfonycasts.com/screencast/last-stack
I can tell you, however, to continue using Encore if you want to use React (or if you're building a full SPA in React, use their frontend tools and Symfony as a pure API).
Cheers!
"Houston: no signs of life"
Start the conversation!