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:

.rw-popup-container.rw-calendar-popup {
  width: 24em !important;
}
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:

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

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

export function *doRequestProfile(action) {

  try {

    yield put({
      type: types.REQUEST__STARTED,
      payload: {
        requestFrom: 'my-saga'
      }
    });

    const profile = yield call(api.fetchProfile(action.payload.accountId));

    yield put({
       type: types.PROFILE__SUCCESSFULLY_RECEIVED,
       payload: {
         profile
       }
    });

  } catch (e) {

    yield put({
      type: types.PROFILE__FAILED_RECEIVING,
      payload: {
        message: e.message,
        statusCode: e.statusCode
      }
    });

  } finally {

    yield put({
      type: types.REQUEST__FINISHED,
      payload: {
        requestFrom: 'my-saga'
      }
    });

  }
}

export function *watchRequestProfile() {
  yield* takeLatest(types.PROFILE__REQUESTED, doRequestProfile);
}

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 :

const profile = yield call(api.fetchProfile, action.payload.accountId);

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

How I Fixed: unresolved variable or type await

Ok, super easy one here, but as a newbie to async / await this did catch me out.

Let’s pretend we have a function:

export function login(username, password) {
  const requestConfig = {
    method: 'POST',
    mode: 'cors',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ username, password })
  };

  const loginResponse = await fetch('https://your.api/login', requestConfig);

This will present an error in WebStorm, and Googling came up only with a bug report from 2015.

In my case, WebStorm would give two different error messages:

webstorm-async-await-expecting-newline-or-semicolon

orwebstorm-async-await-unresolved-variable-or-type-await

Ready to kick yourself?

export async function login(username, password) {
  const requestConfig = {
    method: 'POST',
    mode: 'cors',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ username, password })
  };

  const loginResponse = await fetch('https://your.api/login', requestConfig);

This I tell you brother, you can’t have one without the other 🙂

 

Using async / await with React

I’m currently toying with thunks vs Sagas.

The idea of re-writing a significant portion of my app’s API connectivity (from thunk, to saga) is not entirely thrilling. However, sagas do appear to be the better solution given what I currently know, and would choose them if starting again from scratch.

The gist of my problem is that thunks have added in a layer of complexity – but they work.

For any API call that should be authenticated, I need to catch the call using a middleware and then add the necessary token, and so on.

Combine this with Redux Form, however, and I am left with a bit of a head-scratcher. This middleware is generic. If certain calls fail, I need to map the response (containing error messages) to an object that Redux Form understands, then dispatch the stopSubmit action.

Anyway, enough about my problem.

Before making the switch I found a potential solution that involves using async / await. Being a sucker for new and shiny, I wanted to get it into my project.

Simply trying to use async / await resulted in an error for me:

Uncaught ReferenceError: regeneratorRuntime is not defined

Boo.

To fix this, I needed to import the babel-polyfill. However, a thing I found out is that you can import this dependency once in one of your top level components, rather than per file.

For example, in my project I have an App component which contains a container which all other components in the app render into.

I added the single line:

import "babel-polyfill";

as the first line in the file, and nowasync / await works just fine.

These other two files may help in setting up:

  "devDependencies": {
    "babel-cli": "6.14.0",
    "babel-core": "6.14.0",
    "babel-es6-polyfill": "1.1.0",
    "babel-jest": "16.0.0",
    "babel-loader": "6.2.5",
    "babel-plugin-react-display-name": "2.0.0",
    "babel-plugin-transform-async-to-generator": "6.8.0",
    "babel-plugin-transform-react-constant-elements": "6.9.1",
    "babel-plugin-transform-react-remove-prop-types": "0.2.9",
    "babel-preset-es2015": "6.16.0",
    "babel-preset-latest": "6.14.0",
    "babel-preset-react": "6.11.1",
    "babel-preset-react-hmre": "1.1.1",
    "babel-preset-stage-1": "6.13.0",
    "babel-register": "6.14.0",

 

{
  "presets": [
    "latest",
    "react",
    "stage-1"
  ]
}