Creating reusable components using function wrappers (with Javascript)

Creating reusable code is hard. I know, you have crappy deadlines coming up and you just need that feature today. But, before you go ahead and just dial in that feature, consider the future implications of it. Your code doesn’t die tomorrow, it doesn’t die next week, your code lives as long as the product does. Keeping that code base small and understandable is what ensures that working on the project remains as maintainable as possible. That’s the real reason why reusability is so important. However, that’s a discussion for another day. Today I’m covering one part of the puzzle, which is integrating wrapper functions.

If you want to look at the full body of this code, all of it can be found on my github here.

What is a wrapper function

Put simply, a wrapper function is a function which wraps another function. The underlying concept to this is that you write a function that makes functions. You folks are smart, so let’s get straight to our example. Let’s make a function that only returns true if a user has a particular role.

exports.onlyAllow = function(roles)
{
  return function(user) {return roles.includes(user.role);}
} 

What does this do?

So just now, we’ve created a function that expects a number of roles that returns a function, that expects a user which, if the user has one of the prescribed roles, it returns true, otherwise, it returns false. So an example use of it would be

const {onlyAllow} = require('good.js');
let onlyAdmins = onlyAllow(['admin']);//Creates our function
console.log(onlyAdmins({role:'admin'})//Resolves to true

Where are you going with this?

I’m trying to show off the idea of modeling specific behavior instead of specific cases. So in a theoretical app, a specific behavior may be “only allow these things”, which you saw above, another example behavior that I don’t think is as useful or safe for that matter (Meaning admittedly this is kind of stupid) would be something that doesn’t allow certain roles.

exports.dontAllow = function(roles)
{
  return function(user) {return !roles.includes(user.role);}
} 

This particular tidbit may be useful in some middlewares for some apps, but that’s not the point. What you should grasp here is the idea that we’re modeling this particular behavior not a specific case.

What do you mean by a specific case?

When I say that, I’m referring to some yahoo thinking that it’s ‘self documenting’ to do something like this.

exports.isAdmin = function(user)
{     
  return user.role == 'admin'
} 
exports.isWizard = function(user)
{     
  return user.role == 'wizard'
} 
exports.isLizard = function(user)
{     
  return user.role == 'lizard'
} 

Now, what we’ve effectively done here is hardcode every single last role in our made up app. The issue with this is that each of these things don’t reflect a specific behavior we want to capture, they reflect a specific instance of a behavior. The next logical step here would be to also code isNotAWizard, isNotALizard, and isNotAnAdmin, which I’ll spare you for the sake of brevity. I know that reading this you’re going to tell yourself “I’d never code that” I’ve said the same thing and sometimes crunch time rolls around and it just happens. We all do it, it’s a normal part of day to day programming or even happens unknowingly. We’re not wizards (But some edge cases allow us to be lizards) and are unable to see into the future. Broken windows are a part of life, but we should always be vigilant of them. Just look at these mocha unit tests as an example. This is a bit of a long code block, so feel free to only give it a cursory look

const expect = require("chai").expect;

describe("Check Authorization Level",function()
{
  describe("bad wrapper example", function()//6ix9ine
  {
    
    let admin = {name:'brad',role:'admin'};
    let wizard = {name:'brad',role:'wizard'};
    let lizard = {name:'brad',role:'lizard'};
    it('tests for isAdmin',function()
    {
      expect(role.isAdmin(admin)).to.equal(true);
      expect(role.isAdmin(wizard)).to.equal(false);
    })
    it('tests for isWizard',function()
    {
      expect(role.isWizard(wizard)).to.equal(true);
      expect(role.isWizard(lizard)).to.equal(false);
    })
    it('tests for isLizard',function()
    {
      expect(role.isLizard(lizard)).to.equal(true);
      expect(role.isLizard(wizard)).to.equal(false);
    }
  })
  
  describe("good wrapper example", function()//The real slim shady
  {
    let admin = {name:'brad',role:'admin'};
    let wizard = {name:'brad',role:'wizard'};
    let lizard = {name:'brad',role:'lizard'};
    let onlyAdmins = onlyAllow(['admin']);
    let noLizards = dontAllow(['lizard']);

    it('only allow tests',function()
    {
      expect(onlyAdmins(admin)).to.equal(true);
      expect(onlyAdmins(lizard)).to.equal(false);
    })

    it('Dont allow tests',function()
    {
      expect(noLizards(wizard)).to.equal(true);
      expect(noLizards(lizard)).to.equal(false);

    })
  })
})

Our bad testing overhead is a bit larger than our good example. Take the long view here and consider what these two tests will look like with four cases; five cases;ten cases! We don’t need to update our good test cases because all they test are our two behaviors: “Allow this” and “Don’t allow this”. In our bad example, we have to edit our codebase directly to add in this behavior (already kind of icky), which grows it by a few lines, after that we have to add our tests with also grows it by 3 lines (5 if you want to include “isNotWizard” and the like). That’s a lot of growth of nothing vs 10+ lines per case, all because someone didn’t recognize a good place to use a wrapper function.

To Wrap Up (ha)

Use wrapper functions. They’re great at automating specific cases into code behaviors. I know a place that I use them extensively are ExpressJS middlewares, but try to think back to some earlier projects where you accidentally hardcoded each case and consider if you could have employed wrapper functions to alleviate that issue.

Another thing to keep in mind this doesn’t just apply to javascript. Many other languages support similar features, such as decorator functions in Python. If you want to employ something like this in your language of preference, look it up. There’s a wealth of options in many languages to cover this topic.

How Martial Arts Helped My Programming

Need a new hobby? Like programming? Great! You should learn a martial art. Any martial art. It really doesn’t matter what it is. I personally like boxing, BJJ, and fencing but as long as you’re learning a system, and exercising that system with someone else, this article will give you some insight into how learning martial arts helped me and may help you as a developer.

A New Way to Think About Systems

If you’re developing software, you’re probably a bright baby. Good on you! You can construct the universe in your brain using binary lambda calculus. To me though, that’s just the start. You should start challenging that meat car you drive around to learn in a brand new difficult way, and understand how things fit together in a whole new light.

Learning martial arts is surprisingly like dancing, and not that stuff you do at the club where you awkwardly shuffle , it’s more like swing dance or ball room and there’s a flow to it; A rhyme and reason to each movement. . When you pick up on that flow and rhythm you’ll chain together all of those techniques fluidly and flawlessly. This is what people call a “flow state”.

You’ve probably been there when you’re programming. Just banging out solid line after solid line of code, and getting that five hour commit done in one hour. That’s a hell of a feeling. Challenging yourself to learn a physical system of movement really gets your body in tune with itself and makes finding that rhythm so much easier.

Martial arts are all in the moment. If you don’t slip a punch, you’re going to get your vibe checked. You don’t want to get your vibe checked fam. That spontaneity moves your head away from the flow charts, and into the flow. By finding yourself getting into the moment, you open yourself to flow states more easily, not only in your martial arts, but in your conversations, and yes, your programming.

Determination To Be Better

When you start out in any martial art, you will probably suck. The same is true of programming. That breaking in period is where you learn how to be humble and how to accept help from others. If you’re new to programming/development, that mindset of accepting help from more experienced members in the development process is crucial. You need to be constantly looking for ways to improve your craft; how to slip a punch a bit closer, or how to parry an attack as late as possible.

If you’re in the right head space as a martial artist, you’re constantly looking to find someone who can kick your butt 6 ways to Sunday, because those matches are where you can learn the most. The same is true for a developer. You need to be ready to talk to a senior and accept that he will say your code has some really bad smells in there.

When you hear that, your first thought cannot be “Well up yours chump, my old job thought my code was great.” If the master says your Kung-fu is no good, he’s probably right. Learning to take criticism as an opportunity to learn will help improve your code far more than resisting it and allowing pride to hinder you.

The same can be said in the other direction. If you’ve risen to a senior position in a school, you are taught that your mindset isn’t to destroy newbies that walk through the door. That is how you scare people away from ever wanting to do that task again. Your job is to point out their mistakes and help them learn. That may be in the form of pointing out those mistakes by punishing them in practice, but you will learn the difference between teaching through example and flexing your knowledge like a jackass.

Dealing With Confrontation

If you shrink and buckle in confrontation, or can’t control your temper, see a therapist. After that, go pick up a martial art.

Often times in the office we find that project managers give us unrealistic requirements, our coworkers upset us or any myriad number of things. If you let these things get to you, your work will suck. Both in quality and in experience.

You can’t be a prick, and you also can’t give in to every demand. Neither of those things will help you in the long run. To find that balance, I strongly suggest learning a martial art.

Fighting is scary. Especially if you’re like me, and you don’t like hurting people. That fright is what cultivates the mutual respect that martial artists have for one another. When you go to train with somebody, you’re effectively asking them if you can use their body as a training dummy. In my eyes, that’s straight validation and that kind of positive reinforcement from another person.


With that being said, I hope this article has encouraged you at least give martial arts a try, and good luck on your programming journey.

Organizing your next NodeJS+MongoDB App – Part 1

When dealing with a project of any real substance, one needs to plan (what a thought!). Often this takes place at the diagram level and perhaps even at a technology selection level. In this multi-part post, I wanted to share my method of organizing my app’s backend. In this portion, I’ll be discussing the general layout of our app and explain what each subfolder will hold. Once we’ve established that, in the next post I’ll be going into the nitty-gritty of how some of these bits fit together

Why Read This Post?

You Want Easier To Maintain Files

You don’t want your projects to become 2,000 line monster files. A good developer doesn’t just sit down and start 💩ing out code. Organizing your work into multiple, easier to understand files will slow you down in the short run, but over the life of a 3-6 month project it will pay off in spades.

Your Code Needs To Be Maintained By Someone Other Than You

It’s not just a possibility; it’s an inevitability. Having your project organized into a small set of recognizable folders/files makes wrapping someone’s head around a project much easier than having them read several unrelated files and hoping they fit them together or worse, traversing a disorganized mess of files/folders.

What You Need To Know

Actually not much for this portion! A lot of what you pick up from this post applies to programming in general.

The General Layout

Most of my mongodb+express projects involve the following files/folders

  • Server Folder
    • Schemas
      • SomeSchema.js
      • AnotherSchema.js
      • Schemas.js
    • Routes
      • SomeSchemaRoutes.js
      • AnotherSchemaRoutes.js
      • Routes.js
    • Helpers
      • WhateverYouNeed.js
      • othergoodies.js
  • Files
    • server.js
    • cluster.js

Schemas

The Schema’s folder will hold all of our MongoDB schemas. Each file in this folder will describe a different schema in our database. In most cases, this suffices however in some situations where an object has many methods, I may even have a “SomeSchema” folder with a separate “SomeSchema.js” and a “SomeSchemaMethods.js” file, but more on that in the second post.

This allows us to have all of our schemas in one nice place. To tie them all together we will import each and every one of them into the “Schemas.js” file. This acts as our single access point for our schemas for the rest of our app. Ideally, this will only Routes.js, but in some rare cases, we may need to import a schema else where.

Routes

Routes will handle all of the routes of our app(big surprise huh?) So if we want to create, read, update or delete something, we do it here. Some nice benefits of this are that we can separate database logic and app logic. So if we wanted to implement an extra method from the server that doesn’t interact with the database, we can do it in a single location that is separated from the database logic. For instance, if you had a courtesy route from the app to check if a login token is still valid, you could implement that here.

Helpers

This is our “doesn’t fit neatly into either category” where I usually store my JWT encrypter/validator, validator functions and the like. This is also a good place to store our various middlewares. The important part is that we put all of these miscellaneous functions in one neat area instead of rewriting them all over the place.

Server.js/Cluster.js

This is where we tie it all together. In this set of files, we import all of our routes and various middlewares. After structuring everything in the way we did we can describe our server in one neat, clean line of code. This means the next guy who comes around will understand exactly what is going on as soon as they see it. There should be no need for them to look into any of the aforementioned folders unless they wanted to understand the specific implementation of the methods.

In the next post, I’ll be going into detail in how all of these ideas fit together in the code and what I’ve described looks like.

Adding custom validators in MongoDB+Mongoose

Today we’re going to add custom validators to some of our documents in Mongoose.

Things you’ll have to be familiar with for this article

  • MongoDB
  • Mongoose
  • Nodejs

Why make custom validators?

When dealing with data sent over the web we often find that the inputs we are given tend to be suboptimal. We need some way of relaying to our end users that they’re not meeting our input needs. This is where validators come in. We can define a function that will arbitrate what is and isn’t an acceptable input for a given field. To get started properly let’s define a model and give it a few fields.

const Mongoose = require('mongoose');
Mongoose.connect('mongodb://127.0.0.1/SomeDB',
{
  useNewUrlParser: true,//to get rid of annoying 
  useUnifiedTopology: true,//warning messages

});
//Now that we're connected let's make a user schema


const Schema = mongoose.Schema;
const HorseSchema = new Schema
({
  name:{type: String, required:true},
  color: 
  { 
    type: String, 
    required: true
  },
  bad:{type: Boolean, default: false},
   

});
Mongoose.model('user',UserSchema);//and model that bad boy in our DB

Now that we’ve laid out our schema we can add some validators. In this instance, we really don’t want folks to give us “green”, “magenta” or “rainbow” horses. To prevent this, we’ll implement a simple validator object that will check if our document’s color is a fit and if it does not contain our desired color it will complain with a provided reason.

ColorValidator =
{
  validator: function(documentColor) 
  {
    colors = ['red','brown','yellow','white','black']
    return colors.includes(documentColor);
  },
  message: 'Please select a valid color',
  reason: 'A non-normal color was provided'
}

const HorseSchema = new Schema
({
  name:{type: String, required:true},
  color: 
  { 
    type: String, 
    required: true,
    validate: ColorValidator
  },
  bad:{type: Boolean, default: false},
});

Mongoose.model('user',UserSchema);//and model that bad boy in our DB


That wraps up our tutorial. If you’re interested in extending this code yourself and implementing it in your own project, simply adapt the “validator” part of the ColorValidator object and shoehorn it into your own work.

Consuming Axios in a Vue + Vuex project

This tutorial focus will show you how to assimilate Axios into your tool belt for use in future projects to help save you time and headache.

Prereqs:

  • Basic knowledge of
    • Vue.Js
    • Vuex
    • Axios
  • A preexisting Vuejs app with Vuex

What are we doing and why?

We are taking the Axios plugin for Vuejs and baking it into our own custom GET, POST, PUT and DELETE functions for future projects in a scalable, reusable manner, that will help stop some bad smells from appearing in your code.

Getting Started

Make a new file called “CRUD.js” This is where we will store all of our CRUD functions. let’s create a basic “GET” wrapper for Axios with some minimal error handling.

import axios from "axios"

const GetFunction = async function(route,params,headers)
{
    try
    {
        var results = await axios.get(route,{params,headers});
        return results.data;    
    }
    catch(error)
    {
        return error.response.data;
    }
}
export const Get = GetFunction;

Doing this alone only gives us the benefit of our own custom error handling. Which is nice but we can do much better. In the app where this solution was ultimately handled, the headers from the website did not change between requests, neither did the route. All we have to do to exploit this is add a few lines to our code so we may remove a few arguments from this function call

import axios from "axios"
import store from '@/store/store'

const GetFunction = async function(params)
{
    var address = store.state.address; 
    var headers = store.state.headers;
    try
    {
        var results = await axios.get(address,{params,headers});
        return results.data;    
    }
    catch(error)
    {
        return error.response.data;
    }
    
}

But why?

Basically this eliminates some headache for us down the line. By referring to our state we can refer to our API backend and our token simply by calling our “Get” export from our module. In the event that our API’s address changes, such as when we have a different IP/address from development to deployment, we don’t need to change every single Axios call in our project. Simply change what our state for what the address is, and then we can move on to deployment with a great deal less of worry on our shoulders.