How I Fixed: Missing Headers on Response in Symfony 3 API

The first time this caught me out, I didn’t feel so bad. The second time – i.e. just now – I knew I had already solved this problem (on a different project), and found my urge to kill rising.

I wanted to  POST in some data, and if the resource is successfully created, then the response should contain a link – via a HTTP header – to the newly created resource.

Example PHP / Symfony 3 API controller action code snippet:

And from the front end, something like this:

Now, the interesting line here – from my point of view, at least – is the final line.

Because this is a newly created resource, I won’t know the ID unless the API tells me. In the Symfony controller action code, the routeRedirectView  will take care of this for me, adding on a Location header pointing to the new resource / record.

I want to grab the Location  from the Headers returned on the Response and by removing the part of the string that contains the URL, I can end up with the new resource ID. It’s brittle, but it works.

Only, sometimes it doesn’t work.

Excuse the formatting.

From JavaScript’s point of view, the Headers array is empty.

This leads to an enjoyable error: “Cannot read property ‘replace’ of null”.

Confusingly, however, from the Symfony profiler output from the very same request / response, I can see the header info is there:

Good times.

Ok, so the solution to this is really simple – when you know the answer.

Just expose the Location  header 🙂

After that, it all works as expected.

What’s In Your Stack?

I’m always curious as to what developers are using in their stacks.

Right now my preferred stack consists of Symfony 3 as a back end / API with a composer.json somewhat similar to:

https://github.com/codereviewvideos/fos-rest-and-user-bundle-integration/blob/master/composer.json#L20

I’ve largely bumped to Symfony 3.2, but the combination of bundles I use seems to remain fairly consistent. Actually I just noticed that the Faker Bundle should be a dev dependency there – my mistake.

I occasionally flirt with other languages / frameworks, but when I need to get things done, I default to Symfony 3 & PHP 7.

Things are somewhat different on the front end.

For the longest time I found JavaScript incredibly confusing and scary. It felt very raw, and easy to make a mess. I’m sure I’m not alone in experiencing the joys of 5000 line procedural JQuery scripts – the kind that crash WebStorm’s code inspection on opening (true story).

Then Angular 1 came along. I’m likely viewing the past through a transcluded lense provider (ho ho, that’s an attempt at a joke btw), but Angular 1 seemed to explode across enterprises almost overnight. The terminology put me off (as previously indicated – transclusion etc), but with so many companies using it, it was hard to ignore.

Angular 1 now seems to be in the process of being replaced. By what? Well, it depends on who you ask.

I’m favouring React, as you might have guessed from the recent video content. It works for me.

In between me settling on React, and actually feeling like I could be productive with it, Vue emerged.

Likely there’s 100+ others I haven’t even heard of, let alone intentionally ignored.

But React is just a view library. Around this you have to build your own stack. And a quick look at the jobs boards will tell you, almost every stack is different. React, and / or React Native? Redux or Mobx? Jest, Ava, Tape, Jasmine, or Mocha? Decided on Redux – then Sagas or Thunks?

Ultimately I’m relatively happy with my current choices (React, Redux, Redux Saga, Jest, btw) but having just tried a small side project with MobX, I’m eager to try it some more.

So I’m curious: what are you using in your current stack, and more interestingly, which parts of your stack do you enjoy, and which do you find painful? Please hit reply and let me know.

This week saw three new videos added to the site:

https://codereviewvideos.com/course/beginners-guide-to-git/video/beginners-guide-to-git-branching

Firstly we covered branching in Git from the perspective of a developer who has never used Git before.

In this video we cover all of my most commonly used commands when working with branches, and then move on to a more real world scenario – handling merge conflicts.

Merge conflicts occur when two (or more) branches contain changes to the same line(s) in the same file(s). There are ways to reduce the chances of a merge request, but at some point you will have to deal with one. It needn’t be scary, and after this video you will have learned how merge conflicts occur, and how to resolve them.

In the past I have recorded some more specific videos for Git (https://codereviewvideos.com/course/git-goodness). If you have a specific topic in mind, I’d be happy to record a video on that subject.

https://codereviewvideos.com/course/react-redux-and-redux-saga-with-symfony-3/video/user-profile-page-part-1

Next up we continue on with our React / Redux / Redux Saga front end to our Symfony 3 API backend.

Throughout this – and the following – video you will see that the process we have already learned whilst implementing login is largely the same for Profiles. It’s also largely the same for pretty much any other screen you need to add. This sounds a little long winded, but hear me out:

The modern front end is just as big a beast as the back end. We’ve got build systems, automated test suites, complex state, authentication, routers, and a whole bunch more.

If you’re anything like me, you end up working on a bunch of projects concurrently. Therefore, you need to be able to switch your focus between multiple different environments with the least amount of friction.

Having a standard workflow – such as component > saga > reducer > repeat – really helps to maintain your sanity.

In this video we cover the component setup, along with adding in some security to ensure only logged in users can visit the profile page.

https://codereviewvideos.com/course/react-redux-and-redux-saga-with-symfony-3/video/user-profile-page-part-2

With our profile page restricted down to only users who are properly logged in, we can make certain assumptions about the application’s state when the user hits the profile page. Namely that they will have a user ID.

Using the user’s ID we can initiate a request for their profile stored in our Symfony 3 API.

However, as we are using Redux Saga, we won’t directly call the API from the component.

Instead, our component will dispatch an action to start the profile request.

We will then create a Saga to watch for these actions. When an action is ‘seen’, we can manage the flow more effectively from a dedicated function. This function will ensure our state is updated to indicate a Request is in progress, then await the outcome of that request, process the successful or failed outcomes, and finally ensure the request is stopped.

It does sound like a lot of work. I can understand why there are those with the opinion that this process is needless verbose. My personal opinion is that this process brings order to larger applications.

Until next week, take care, and happy coding.

Chris

An issue with React Widgets DateTimePicker

When you have the fix to a problem, but don’t know the root cause of why that problem is happening, you have two choices:

  1. Accept you have a solution, and move on, or;
  2. Accept you have a solution, and figure out the cause of the problem.

The problem is, #2 takes time. And that might not be time you have currently.

Dwelling on some problems is not the best use of my time in my current position.

So here’s my problem, and a solution, but I cannot offer you the root cause to this problem. Nor is it the defacto solution, I believe.

Using React Widgets DateTimePicker

I guess you’re either the kind of developer who creates everything themselves.

Or you first try using other people’s.

I wanted a Date Picker, ideally with time, and I would like it to be hooked up to Redux Form.

The good news, Redux Form already works nicely with React Widgets. See the previous link for a decent tutorial. And this code sample.

As a result, I can quite easily add in a Date Time Picker that’s hooked up to my Redux Store. This is good. It pleases me.

It also allows me to start laser focusing my A/B tests.

date-of-birth-as-a-timestamp
You’ve never A/B tested unless you know for sure customers don’t prefer timestamps.

But joviality aside (wait, that was humour?), I did hit a problem along the way:

react-widgets-calendar-size-issue
That’s not so good, Al.

There is a quick fix to this.

Add in a local (S)CSS style:

redux-form-datetime-picker-react-widgets
Better

It’s good, but it’s not quite right. Good enough for me to continue, though has been firmly lodged into the ticket queue under ‘improvement’.

Here’s what it should look like:

react-widgets-datetime-picker-proper

So there you go. Hope it helps someone. It’s unofficial. It’s not the real fix. Any pointers appreciated.

How I Fixed: uncaught at check call: argument [object Promise] is not a function

Earlier this month I started dabbling with Redux Sagas as an alternative to Redux Thunks.

At the time I was highly skeptical – largely around whether re-writing a significant portion of my JavaScript was good use of my time, given that I had no prior experience with generators, and that conceptually sagas sounded pretty hard.

But I kept hitting issues with Thunks. They just seemed so cumbersome, and error prone. I found writing tests for them to be painful, and adding in the Redux API Middleware made that even more complicated.

Ultimately, switching to Redux Saga has been one of the highlights of my current project. I love it. Every problem I have had so far has been made easier through the use of sagas.

But today I hit on a problem I haven’t seen before:

This is a generic version of the code I am using:

I have highlighted the problematic line.

The issue here is that the error in the browser is fairly cryptic. It took me digging into the source code to figure this one out.

But actually the issue is really simple to fix.

The highlighted line above should be :

I was calling my function myself, and then passing the promise on to the Saga… whoopsie daisy.