It’s OK to suck

I’m going to hazard a guess here and say: most people know that learning a musical instrument is hard.

There are exceptions to every rule, and like Usain Bolt didn’t need to learn to run super fast, I’m sure a percentage of the human race is born with a musical acuity that for the vast majority of us, it would take years of constant practice to come close to matching.

But these are the exceptions. The rare, rare… rare exceptions. That’s why we know these people by name. Mozart. Beethoven. Williams (as in John, Star Wars / Jurassic Park / Harry Potter / many others).

However, no matter how great your raw talent, you can always improve.

And more importantly, most of us started off by sucking. Like, seriously, the massive, massive majority of programmers out there in regular day jobs started off as total hackers.

This. Is. Hard.

The first time I put on ice skates, I sucked. I fell, I hurt myself, things were embarrassing.

The first time I went snowboarding, I sucked. I fell, I hurt myself, things were so embarrassing that at one point I slid sideways straight into the wall (Chill Factore – Manchester, btw) at such speed that I had to receive medical attention. Top lols for everyone other than me.

The first time I wrote code, I sucked. The earliest memory I have of programming was writing a game – which was really a set of conditionals – with terrible dialog, and no plot.

There’s only ever one way to improve. You soldier on.

The only difference between you right now, and the vast majority of those around you is persistent effort.

What you need is small, crystal clear, and very importantly: achievable goals.

A goal of “learning Symfony” is not a goal. It is very fluffy. How do you know when you’ve learned Symfony? I mean, it changes all the time. Seriously, check out the blog – – and lookout for articles starting “New in Symfony”.

When I put on ice skates for the first time, a clearly defined goal was to complete one circuit of the rink.

When I strapped into a snowboard for the first time, I wanted to get from the top to bottom, without falling over – and it took me long enough to do this just standing sideways the whole time.


It’s just so broad.

Assuming your goal is currently “to learn Symfony!”, but when you sit down at your computer to learn, you draw a blank, then I want to suggest something to you. Try this course:

Now. Much like my hilarious snowboarding adventures, there is an important take away here:

When you get to the bottom of the hill for the first time, you are not done. You are just done getting started.

At the end of this course you won’t be an expert on Symfony. But you will have an idea of what it’s like to work with Symfony.

I actually encourage you to try Laravel at this point. And maybe even something totally different, like Ruby on Rails, or Django Web Framework.

This is what I did. Add in Yii, Cake, and ZF2.

I sucked at each one.

The one I settled on sucking less at was Symfony 🙂

To make my life easier, I stuck to a very simple example. A blog.

It’s essentially CRUD, but with the added advantage that most frameworks use something similar as their example in their official tutorials (if they have them), or the various beginner friendly community sites (if they don’t).

Along the way, I learned a ton. And with a known outcome, I finished every project – often with code just as embarrassing as any snow-based face plant.

But that’s fine. It’s ok to suck.

Would you watch a series on building a blog? I’d love to hear back from you on this.

Video Update

This week saw three new videos added to the site:

Firstly we finished up our User Profile journey. In this video we implemented the Redux Reducer to correctly update the state of our application, ensuring our user’s id, username, and email are all stored and readily available.

In doing this we can now dynamically update our Profile Page, displaying real data as opposed to the hardcoded / faked data we had been using.

By now we have covered the standard ‘template’ we need to add in any further pages to our application. Firstly we define our component. This component accepts data as props. These props need to come from somewhere – often as a result of some API call.

To manage this API call we use a ‘container’. This container is connected to our Redux Store – in other words, our application’s state. This container is still a component. Aside from rendering our component, it handles initiating the request for our data.

This is done by dispatching an action describing the process we want to take place, such as requesting our user’s profile.

This action is ‘watched’ for by a Saga. This saga manages the process of actually calling the API, and handling the outcome – successful or not.

If successful, we can then send the returned data to our Reducer. The reducers job is to update our application’s state.

When our application’s state is updated, our connected container is able to update the component it renders with the new props, taken from our application’s state.

Pretty much any page we add to our application will follow this process. You can repeat this for the specifics of your own application as needed.

One such example of the above process is in enabling our logged in user to change his / her password.

There’s a bunch of hidden gotchas in this process though.

Firstly, we are going to be working with forms. In our project, that means working with Redux Form. We’ve already covered Redux Form in some detail during the implementation of the Login process.

When changing our password, however, we now want to get a little more user friendly.

Sure, if everything goes to plan, we have a fairly easy journey. We might want to show our user an indication that they clicked the button (which in itself, holds a gotcha), and aside from that, if they successfully change their password, we might want to show a Toast / pop up notification.

When things go wrong though, life isn’t quite so easy.

Firstly, we need to figure out how to tell Redux Form that one, or multiple fields have errors.

Secondly, we need to translate the JSON that our Symfony 3 API returns into a format that doesn’t cause us headaches.

It would also be swell if this all looked quite stylish.

By the end of this video we will have laid the foundations for this process.

I just mentioned that changing the password button text to indicate that a ‘change password’ request was in progress contained a ‘gotcha’. In this video we will immediately address this issue.

To give the game away somewhat, this problem is around using part of the state we created when we made Request Tracking more robust (

The issue here is that we have a field inside our state that indicates – generically – if there is a request in progress.

This is fine, depending on the complexity of our page. For example, when used on the login screen, we only ever have one request – the user clicked login.

However, on our profile page, we ask our API for the user’s profile when we load the profile page.

If we naively rely on this generic ‘is a request in progress’ field then our ‘change password’ button is going to think it’s submitting whenever we load the page. Queue user confusion.

Aside from fixing this bug, we also cover how we might display toast notifications to our users on both success and failure. If this is something you might be interested in adding to your React application, I have covered this in a previous blog post (

There’s still a number of videos to go in this series, but next week we will take a break and switch over to the workflow component series ( There’s a ton of stuff to cover in this series, some of which is currently undocumented over at This is one of my favourite features to be added to Symfony, and is so broadly useful that once you’ve seen it in action, you’re sure to immediately have a bunch of ways in mind to start using it.

Until next week, take care and happy coding,



Published by

Code Review

Code Review

CodeReviewVideos is a video training site helping software developers learn Symfony faster and easier.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.