Lessons Learned: Python to JavaScript

dan_starner

Daniel Starner

Posted on December 12, 2018

Lessons Learned: Python to JavaScript

The following is just some things that I found interesting as I dive deeper into the world of JavaScript.

Some Background

At Bloomberg, I work with a DevOps / Infrastructure team that deals very heavily in hardware, networking, and scripting. This means that everyone on my team is very good with Bash, Ansible, and Python, and can probably rattle off more networking acronyms than seconds in a day.

Shortly after I joined, we started to think about a web dashboard that would manage and automate many of our manual processes and tasks. We were planning all the features to include, and it was going to be so cool...except that I was the only one on the team who knew anything about web development, and even that was a loose association.

My previous experiences were writing backend services and APIs for web companies, but I really had no experience on the front end side of things. For this web dashboard project, I wanted to really dive in and learn React the right way, building out a full application on my own.

What I Learned

Below are just some things that I learned or find interesting about JavaScript, React, and front end development coming from a Python and backend standpoint. Note that I am building a React app, so many of these things revolve heavily around the library.

NPM Dev Dependencies vs Dependencies

I didn't really understand this until I started building Docker images for my Express-React app. In Python, I would always have a dev-requirements.txt file that contained my test and linting libraries and a requirements.txt that held all other dependencies. Its really nice that both of these stay in package.json, cleaning up the project structure and making it easier to automate installs.

Structure Doesn't Matter as Long as It Works

When developing, I am constantly moving files and folders around, trying to achieve the best project structure. I always have the mindset of Will this work if I add more stuff?, and it usually leads to a never ending rabbit hole of project structure management instead of coding.

What I learned from different posts online, and from my own experience, React doesn't care what project structure you use, and so neither should you. Obviously, try to keep it clean and organized, but aside from that, if something works for you, don't bother refactoring it until you have to. I am a fan of my current folder structure that looks something like the following. Note that I omitted files.

.
├── __mocks__
├── bin                # Scripts needed to run Docker image
├── certs              # Any certs I need for local dev. These are mounted to container
├── dist               # Build directory
├── screenshots
├── src
│   ├── assets         # Non-JS or styling assets
│   │   ├── images
│   │   └── jss        # I use MaterialUI, which styles using JSS
│   ├── components     # General use components
│   │   └── hoc        # Higher order components
│   ├── config         # Configuration file for server that loads env to object
│   ├── core           # Anything that is crucial to the React app
│   │   ├── layout     # Core layout components
│   │   │   ├── header
│   │   │   └── sidebar
│   │   ├── pages      # Not Found / Landing pages
│   │   ├── state      # Core managed state, aka users and theme
│   │   │   ├── auth
│   │   │   └── meta
│   │   └── util       # Any usable themes
│   ├── pages          # List of top level React Router routes as 'pages'
│   ├── server         # All code pertaining to the Express server
│   └── tests          # All tests
└── webpack            # Webpack configs for server and client
Enter fullscreen mode Exit fullscreen mode

State Management / Cleaner Components

State management in Python for me doesn't really exist, especially if its for more scripting purposes. I usually favor composition over inheritance, but it was always because of what I learned in school. Writing React components really made this idea stand out.

Components are composed of smaller, possibly reusable components that each level in the hierarchy is responsible for rendering and/or maintaining a specific part of the application. It's a really cool feeling to reduce code lines because I recognized clever ways that components were either related, or could be composed of one another.

The whole idea of the waterfall effect with props and state from parent to children components is really cool to see live, once you understand what is going on. This was something I didn't understand at first, but my code and relationships between components got much better as I understood proper state management.

Promises Are Super Confusing at First

Coming from a synchronous Python / scripting world, JavaScript promises made zero sense to me until about 3 days ago, so don't hate if my examples below are still bad. For the longest time I tried to make Promises synchronous, and I would be so confused at why things like the following returned a promise.

function fetchSomething() {
  const fetchURL = '/something';
  return axios.get(fetchURL);  // returns a promise
}

// Handling the axios call like a synchronous
// function leds to tons of horrible callback 
// and uncaught promise exceptions 🤷🏼‍♂️
function getSomethingHandler(callback) {
  fetchSomething()
    .then(response => { callback(response.data) })
}
Enter fullscreen mode Exit fullscreen mode

But now I understand the whole then(callback), catch(errCallback) flow, and it makes so much more sense. On the next iteration, I rewrote it as the following, which is a bit better:

function fetchSomething() {
  const fetchURL = '/something';
  return new Promise((resolve, reject) => {
    axios.get(fetchURL)
      .then(response => { resolve(response.data) })
      .catch(error => { reject(error) })
  });
}

// Handling the axios call like a synchronous
// function leds to tons of horrible callback 
// and uncaught promise exceptions 🤷🏼‍♂️
function getSomethingHandler(callback) {
  fetchSomething()
    .then(data => { res.send(data) }) })
}
Enter fullscreen mode Exit fullscreen mode

This version stopped many of those callback and promise exceptions. This also allowed my handler functions to expect the data already marshaled into my desired format by the fetch-ing functions. Finally, I started using async and await. I'm still iffy on these, so I apologize if the following isn't 100% correct.

async function fetchSomething() {
  const fetchURL = '/something';
  try {
    // Wait for the axios promise to resolve
    const response = await axios.get(fetchURL);
    return response.data;
  } catch (err) {
    console.log(err)
    return err;
  }
}

function getSomethingHandler(callback) {
  fetchSomething()
    .then(data => { res.send(data) }) })
}
Enter fullscreen mode Exit fullscreen mode

I'm still actively learning more about this asynchronous workflow, but so far its pretty awesome.

Bonus CSS: FlexBox is Amazing

More of a CSS thing, but one of the major factors that kept me from getting into front end design sooner was dealing with element alignment and sizing. No matter what margins or align values I put, nothing seemed to work. This was my first real experience playing with Flexbox in CSS3, and OH SNAP it makes a world of a difference. Between flex-grow, flex-basis, justify, and align-items, positioning things in HTML is made a whole lot easier.

Closing Up

Although there's a lot more stuff I could talk about, these were some of the more major experiences I've had with JavaScript, Express, and React over the past few months. I might write a second post in the future as my project matures.

Thanks for reading 👍😃

💖 💪 🙅 🚩
dan_starner
Daniel Starner

Posted on December 12, 2018

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Lessons Learned: Python to JavaScript
python Lessons Learned: Python to JavaScript

December 12, 2018