What is Redux-Saga?
Redux-saga is a redux middleware library, that is designed to make handling side effects in redux.
As I said before they were introduced to me by Mateusz Bosek, and he liked them. Moreover, since I began using sagas, I’ve also grown to love them and the redux-saga pattern.
The Redux-Saga Pattern
Redux-Saga leverages Generators, allowing us to write asynchronous code that looks synchronous, and it is easily testable – This right here is what makes redux-saga powerful, and this is why I love the redux-saga pattern.
For example, let says you have a user login process which does the following:
Get the username and password from state
Call login API endpoint with the username and password – on success get the user authorisation token
Save auth token in the store
Remove the username and password from the store
Call Settings API endpoint with the authorisation token – on success get the user settings
Set the user settings in store
This is what the saga looks like for the user login process:
In this example above I’ve used what redux-saga calls Effects, these Effects are:
select: Used to select state from redux store (same as getState())
call: Used to call other methods with arguments
put: Dispatches action
So my userLoginSaga is okay. However, It needs some refactoring.
So my userLoginSagaRefactor is much better. The API calls now have their own sagas. Additionally, this version is much better for unit testing. In the unit test I can test each yield, like the following:
This unit test will check each yield. The order is essential, otherwise, the test will fail. There are other forms of testing redux-saga for example redux-saga-test-plan
I am forever grateful to Mateusz Bosek for introducing me to redux-saga. It’s made the applications I work on better and improved my coding experience.
My mission with this blog post is to show you my current development tool-belt for creating a new web application:
What core technology do I use and why?
What packages do I use and why?
How do I structure my code and why?
Starting with the Core Technology
My web-app core technology is React. Why React?
I’ve invested in books, front-end masters courses and many many more hours spent on blogs and tutorials. I’ve also been using it at work since 2017 till now. I know the ins and outs of React quite well, and with React you’ve got React Native as well which allows you to do mobile apps. At the moment React is my default front-end tool, and until something comes along that’s going to dethrone React as React did with Angularjs then I might consider it, but for now, its all React for me.
React-Intl for Internationalising – https://github.com/yahoo/react-intl Why React-Intl?
Before moving to Dubai, UAE. This package would not be on the list because all applications I worked on in South Africa only supported the English language, therefore, there was no need for React-Intl. However, this was just a lazy design because what if we did want to support an additional language we would have to refactor the entire application. So right now any application I work with has React-Intl by default even if only one language is used, at the start. If I need to add additional language support, the application is ready to support that.
$ yarn add react-intl
Material-ui for UI (Layout, Theme and Styling Components) – https://github.com/mui-org/material-ui Why Material-ui?
There’s a massive community behind this open source project. React components that implement Google’s Material Design.
$ yarn add @material-ui/core
Because I used create-react-app to set up my React development. I already have the following:
Jest – for unit testing. I update my package.json file by setting the unit test code coverage.
Typescript – for type checking (In 2019 you must add types to your code.)
Prettier – for code format. https://github.com/prettier/prettier Why Prettier?
No one has time to format their code :D, therefore, let prettier format your code for you. Decide your format rules upfront and let prettier do all the work. I configure prettier with husky and lint-staged to automatically format every file I commit. Therefore all code committed to GitHub is formatted automatically by prettier.
Okay, so now that I covered my core, and my main production and development packages. Next on the list is the coding structure.
With this fantastic React development environment set up with these main packages, and unit test coverage setup. All is useless if the coding structure is not modular or lacks a good structure that can scale.
This is where I set up my root reducers, sagas, etc.
The modules folder is where I create my features for my web-app. Each feature has a components, containers and pages folder. Regarding nesting, before I’ve had a situation where I went crazy with nesting components inside components, this resulted in a complex nesting and over time the structure became difficult to work use. So the rule I use now, is I don’t go past 1 level of nesting. This means in the parent components is on the same level as children components. At first, this seems weird over time, and I got used to it. The same rule applies to containers and pages.
In the shared folder, I place all items which are common or used in multiple places. This also where I place the API interface as well. The same nesting rules apply for shared folder structure.
Currently, this is I what use and its working for me. However, this is not cast in stone; it’s like an evolving style guide. Additionally, the packages and patterns that I am using are working for me right now, once again when I come across a package or patterns which works better or easier, I evaluate it, try it out and then it gets added to my tool-belt. Repo:https://github.com/zulucoda/zulucoda-tool-belt-app
So with this post, I am trying something different. I am just going to tell you about my experience thus far with taking an existing SPA created in Backbone + jQuery and migrating this SPA to React.
I am going to get straight into it, and therefore if you’re new to React, my suggestion would be to check out other blog posts as this will cover advanced topics.
Additionally, I know that many people have written articles & posted videos on such migration. However, when I was reading and watching those videos, I was still missing critical architectural info. So even though sample code and blog post example were made available to me, this still didn’t help me in what I needed to do.
Migration Planning Phase
After doing research, I presented a few ideas to my colleagues and Head of Development. There where two main ways of going about our migration:
Complete Clean Refactor
Complete Clean Refactor
We start from the ground up and re-build everything. There’s a point in the life of a product where a complete clean refactor is not feasible. When you have a product that is successful and clients are happy. Yes, the underlying tech might be outdated, it might take longer to deliver new features and maybe its no-longer developer friendly.
Additionally, asking business just for a budget to refactor an existing product? It’s no wonder why business does not trust its tech people.
After presenting this information to the team, the Hybrid Solution was a clear winner.
Before joining the team, I had been working on a React SPA that used a NodeJs + Express API. I was working on both of these code bases. Additionally, we had a React Native application using the same API. Moreover, before that, I was working on an Angularjs (1.5) App. Therefore I had no Backbone experience. However, this would not be an issue.
So we had an idea that we should do a hybrid solution, but we didn’t know how we would do it? Therefore it was suggested that we start by prototyping this hybrid solution.
The Prototype Phase
This phase would last two weeks, and we would use the learning’s from this phase to create an architectural solution, which we will use going forward for our smooth react migration.
When I presented my solution to my colleagues, they were happy with the outcome. However, they challenged me to simplify the architecture and use Redux Architecture with Redux-Saga as middleware and making use of Redux-Saga side effects for rendering components onto the DOM. This would get rid of the iframe and simplify the middleware to dispatch actions to redux and sagas and make use of Backbone events. This way any new developer joining the project would not need to learn my custom middleware but use existing tech knowledge they know about Redux and Backbone.
The Final Architecture
I cannot post the actual code as that is company property. However, the beauty of these patterns I used during the prototype phase are so simple and straightforward that I have recreated them for this blog post.
Legacy SPA App
React-Middleware – used for dispatching actions
So the Legacy SPA does not have a clue about React it just continues to run as it does currently. We have a React-middleware which dispatches actions from the Legacy SPA to Redux or Sagas.
Storing User Info in Redux
So example currently on our SPA when a User logs in, after login, the react-middleware dispatches an action with User login payload, this is sent to Redux and the User data is stored in our Redux store for use for by our React App.
Rendering/Mount React Component
This is probably one of the coolest things I learnt about React which is the possibility of rendering multiple components onto the DOM. Now I didn’t know React could do this. However, I recently learnt from a conference talk that this is how they use React at Facebook.
In our SPA we decided to use redux-sagas side-effects to also render components onto the DOM for us. Therefore, on the Legacy SPA, an action is dispatched with a DOM element ID. Then a saga listening to this action uses that element ID to render a component onto that DOM element using ReactDOM.render(). The great thing about this is we are respecting the Redux Architecture, by simple dispatching an action, this easy to understand even for new people joining our team.
Un-Rendering/Dismount React Component
Where are we now
We have just finished our first feature in React, and it is working great inside the Legacy SPA. We are about to start creating more new features using React rapidly. We will also start looking at converting existing functionality over to React. The remarkable thing about this Hybrid solution, is we are keeping business happy by delivering the features they want. We as developers have created a great developer experience for ourselves.
This is a photo of my Alfa Romeo Giulietta Quadrifoglio (QV), I bought this car brand new in June 2011. It had zero kilometres on the clock, plus I was and will always be the single owner. My Alfa Romeo Giulietta Quadrifoglio (QV) has just reached 200 000KM on the clock. Furthermore, it will be my QV’s 8th birthday. You might look at kilometres driven and remark at how many kilometres I have raked up in 8 years, moreover they were eight incredible years of driving. Every opportunity I got to drive, I did. I have been all over the Gauteng province, including to KwaZulu Natal the land of my Zulu people. What I love about my Alfa Romeo Giulietta Quadrifoglio is that every kilometre that has been driven has always been exciting there has never been a dull moment or a time when I had enough.
My Alfa Romeo Giulietta Quadrifoglio (QV) still surprises me with every acceleration. Moreover, the handling has always been exciting. I am not sure what the Italians do when they create these fantastic sports cars. You can feel the passion and love that has been transferred to all their sports cars. This is my 1st Alfa Romeo, and I love it.
Before my Alfa Romeo, I had an Audi A4 B8 2TDi the car was good, well built, plus had an excellent sound system. After three years with it, I had enough. I was looking for something else, I was ready for another car. When I had the Audi, there was not much excitement after one year of owning it. The novelty had worn off. There are only two things I missed about the Audi, the sound system and after-sales service received after buying the car. One other thing which was unique about Audi South Africa was they sent me a gift after purchasing my Audi. I’m not sure about other countries, but I think this is where Alfa Romeo South Africa can learn a thing or two about after-sales service from other luxury brands. Or though I don’t want to dive too deep into this, also let me make it clear, I’m referring to the craftsmanship regarding servicing their cars, and I am relating to my experience on how well they managed the perception and their communication with their clients. Don’t get me wrong Audi’s are not perfect, they do break. Also, they’re after-sales people also do make mistakes. I can account two experiences that I had which backs this statement up:
My Audi service representative told me that my Audi had break sensors; therefore, it will indicate to me when the breaks needed changing; however, this was not case plus this ended up damaging the brake disks.
My Audi broke down in traffic, luckily I was still able to drive.
However, these two experiences above were managed very well by Audi when the car was booked in for service.
Anyway, I digress from the topic, coming to back to the primary subject which is my Alfa Romeo Giulietta QV has made it to 200 000KM, therefore crushing the fears of “reliability”. Everyone who knew I had an Alfa Romeo, would congratulate me on my Italian car, then crack some clever joke like “at least your car will look pretty on the side of the road after it breaks down”. Now you can imagine the confidence this gave me in the start, knowing that someday I might be stuck on the side of the road with a broken car. At first, I brushed it off by saying it’s okay it’s still under warranty therefore if I do get stuck, the warranty will cover it. Moreover, do remember that this is my first Alfa Romeo. So it’s like these people (Alfa Romeo haters) were saying I’d never make it past 100 000KM. The fact that I have made it to 200 000KM proves to me that Alfa Romeo Reliability myth has been BUSTED.
To summarise, this is my first Alfa Romeo that I have owned. Moreover, I have been pleased with what my Alfa Romeo has been able to achieve. Yes, there were ups and downs, however, I can call recall more fantastic moments though. Every morning I am greeted with this beautiful car. Furthermore, it is at that moment I know I am about to have fun driving to work. Bellissimo, Forza Alfa Romeo.
Name: Alfa Romeo Giulietta Quadrifoglio
Vehicle Mechanical Warranty: 5 years / 150 000KM
Service Plan: 6 years / 105 000KM
Power: 173kW / 232Bhp
“hard work overrides talent” Curtis 50 Cent Jackson quote to Kendrick Lamar
I too relate to this a lot because growing up I wouldn’t say that I was super talented, I was fortunate enough to be surrounded by talented people especially at Parktown Boys’ High School. I was so blessed to have so many friends, from different backgrounds, different ages and with so much talent.
It was amazing to watch my talented friends do their thing whether it was sports, academic, drama, and other activities. Their passion rubbed onto me, so I became passionate.
I found my niche in programming, I still remember the first time I saw a programming language. I had just started High School at Parktown Boys’ High (Best boys’ school in the world) and I was in the boarding house called Vulcans. One of my senior’s who’s nickname was snakey (because of His small frame) was at the computer centre working on His computer science home work. The screen was blue, and the text on the screen was yellow and I remember seeing it and being so amazed by what I saw on the screen. At the time I didn’t know what I was looking at, but I really liked what I was seeing. So I asked Andrew (Snakey) what is that? and He told me this is a programming language called PASCAL. I told Him I want to do this as well. He then told me that I must work really hard in order to understand the basics of programming because once I know the building blocks of programming and I have a solid foundation, I’ll be able to code anything. So my journey began…
In 2005 I started my professional software development career at a small IT company called amaDigital. There I was given the opportunity to take lead working directly with clients and building entire web application systems. Fast forward many years later and I am now Tech Lead working a large corporate. Like I said when I started this post, I’m not the most talented person, what I have is the ability to visualise what it is I want or need to create and I put the in the work to create that.
Being a programmer is awesome, there’s so many cool tools & techniques being created by amazing programmers. I myself believe it’s my responsibility to use these tools & techniques to create applications which will somehow contribute to society. For me it would be awesome to be known amongst the best programmers as that guy who created that amazing web application which revolutionised how business is done in Africa. and When they ask me How I did it? I’ll just say Hard Work and self belief.
The first time I deployed my rails app, I deployed with standard Web brick server. In fact I deployed a couple of Rails apps using Web brick. It was only after listening to a podcast from Ruby Rogues I realised I needed to update my applications. During this podcast everyone made fun of Devs who deploy Rails using Web brick. I was so ashamed that I was one those Devs, so I decided to fix the problem.
Why is it not good to use Web Brick server in Production?
Well Web brick is more of a development server thus it is only meant to be used in development environment.
How to resolve this problem?
It’s actually simple, all you need to do is specify an alternative server in your Gemfile under your Prod settings. The server which I’m using is thin . It’s that’s simple.
If you’re running your rails app in Heroku change your Procfile
group :production do
web: bundle exec rails server thin -p $PORT -e $RACK_ENV as
Do you have more tips and tricks to share regarding deploying Rails Web App? If you do please kindly share them in the comments section.