Welcome to the tech community!

As an admin of the Cleveland Tech Slack group and historically an active member of the local tech scene in Northeast Ohio, I get to field quite a few questions from new, budding programmers looking for a community to connect themselves with as they continue to grow. While my answer may change a bit from person to person in regards to what they are trying to get out the experience, it normally boils down to the following resources:

  1. Cleveland Tech Slack
  2. Launch League
  3. Local Meetup Groups
  4. Additional Resources

Cleveland Tech Slack

Located at https://cleveland-tech.vercel.app is a self signup form to get added to what I believe is the best resource for people in Northeast Ohio looking to build their technical network. There are channels dedicated to different technologies, a #jobs channel for finding opportunities for local/remote-friendly jobs, and works as a nice way to converse with someone who may happen to work at a different company.

Launch League

A great network of energetic entrepreneurs,  developers, and designers this is a great resource to tap in to the Akron, OH communities. While their focus is more directly geared towards entrepreneurs, they have a wealth of specialty user groups that they help to manage. You can sign up at http://www.launchleague.org for free which will give you access to their Slack group with another collection of wonderful channels.

Local Meetup Groups

If you’re interested in connecting with people, nothing beats getting out there and saying introducing yourself. This is how I got my start over a decade ago networking with the amazing talent this area has to offer. You can create a free account and search for groups related to Ruby, Go, entrepreneurship, and more at https://www.meetup.com.

Additional Resources

If you’re interested in perusing local companies, services, and resources there’s a great list at https://github.com/mrfright/cleveland-tech.

 


Those four items are a great way to get started with our local tech scene and to start building the relationships that will help you build your career.

One more piece of generic advice is to try and find a person who can help guide you through the troubled waters of technical and professional decisions. There is a #mentor channel in the Cleveland Tech Slack if this is of interest to you.

Bigger Team; Larger Office

I’m happy to introduce Christopher Stoll, the newest member of the Coffee and Code family! Chris brings a wealth of programming experience and team building skills and acts as an anchor for our company’s future direction. I am very excited for what he brings to our group and what that means for the future of Coffee and Code.

Building a talented, well respected team is difficult work and I’m extremely proud of what we have accomplished together since Eric joined me over three years ago. However, Coffee and Code has never been known for being sedentary, and are constantly looking towards the future and how to provide even more value for our clients.

Our future includes building a friendly environment for fostering future generations of developers and designers. Chris’s skillset will help us to not only continue to produce top quality work, but will help to further build our specialized team whose talents amaze our clients and outshine our competitors.

In addition, our future facing growth has paved the way to our brand new office in downtown Akron located between two green spaces and next door to a coffee shop. We need room to develop our desired company and our new space provides just that. We’re still in the process of making it feel like home, but we’re planning to have an open house as soon as the dust settles.

If you’d like to be invited to our open house, or would like to keep tabs on what we have going on, please sign up for our newsletter.

We are still laser focused on delivering the same high quality output that our clients have come to expect. Our entire company focus at this point is producing a more cutting edge and future focused team that can help our clients execute on their ideas while providing a sense of direction and stability in a seemingly unstable technological landscape.

– Jonathan Knapp, President and Founder

What does AWS Lambda support?

Anyone who’s developing in JavaScript knows the extremely useful features that have been creeping into Node and different web browsers. They also know the frustration of determining which features are supported and the pain of forced polyfills and code transformations tacked onto our build processes.

At Coffee and Code, I’ve been doing quite a few projects involving AWS Lambda which provides a Node.js runtime, but I kept having to look up whether I could use a specific ES6 feature or not.

How do I find out what features are supported and which I’d require something like Babel for?

Kangax provides a great resource for determining what features are supported in different JavaScript environments. However, they only show the major versions of Node.

node.green is a fairly new resource that focuses on more releases of Node and also utilizes the Kangax test suite, but they don’t list results for older versions of Node.

That’s why I built whatdoeslambdasupport.com, a website to quickly see what tests pass or fail for each Node runtime that AWS Lambda supports.

The tests results are generated by running the Kangax tests inside each of the Node.js Lambda runtimes so there’s no “it works on my machine” issues with the test results.

You can use this resource to determine what JS features you can use in your Lambda projects, or to make a call whether including something like Babel makes sense.


If you’re interested in hearing more about how I’ve used Lambda for client projects, I’ll be speaking at Pittsburgh TechFest and Erie Day of Code over the next couple weeks. Stop by and say hello!

Converting Documents with OpenOffice / LibreOffice

Did you know that you can convert documents with a headless version of OpenOffice or LibreOffice? If you pass a few commands to the soffice binary, you can convert one document type to another.

My examples will include paths for LibreOffice on a Mac, so make sure to adjust accordingly.

The following will convert all Word documents on my desktop to PDFs in the convert folder on my Desktop:

HOME=/tmp TMPDIR=/tmp /Applications/LibreOffice.app/Contents/MacOS/soffice --headless --convert-to pdf:writer_pdf_Export --outdir /Users/jon/Desktop/output/ /Users/jon/Desktop/*.doc

Make sure to include HOME=/tmp TMPDIR=/tmp before the command or it will run into permission issues and be unable to complete the file conversion.

Some believe writing files to the /tmp directory is a better approach, but I didn’t end up trying it myself.

Thanks to: https://ask.libreoffice.org/en/question/2641/convert-to-command-line-parameter/

Returning Simple Data with Tastypie

It’s not everyday that I find myself in the land of Python, but I recently started working on a project with a friend’s company to help them reach an upcoming deadline.

The project uses Tastypie to generate an API based on Django models, which works great! However, when I wanted to return generic data I ran into a bit more resistance than expected.

The API pointed me to Using Tastypie With Non-ORM Data Sources, though I was hoping for something less heavy handed. I didn’t want to make resourceful routes around a custom data source, I just wanted to return a simple json object.

I ended up with the following solution:

# Custom object that we'll use to build our response.
class CustomResourceObject(object):
    def __init__(self, name=None, label=None):
        self.label = label
        self.name = name


# The Tastypie resource that will return our data.
# Make sure to inherit from Resource instead of ModelResource.
class CustomResource(Resource):
    # You will need to add fields for each property
    # that will be returned in the response.
    label = CharField(attribute='label', readonly=True)
    name = CharField(attribute='name', readonly=True)

    class Meta:
        # Start by disabling all routes for this resource
        allowed_methods = None
        # Allow the `get` index call where we will return data
        list_allowed_methods = ['get']
        # Use the custom object we created above
        object_class = CustomResourceObject
        # API endpoint for this resource
        resource_name = 'custom_endpoint'

    # Create our array of custom data
    def get_object_list(self, request):
        return map(lambda val: CustomResourceObject(label=val[0], name=val[1]), DjangoModel.CHOICES)

    # Return our custom data for the API call
    def obj_get_list(self, bundle, **kwargs):
        return self.get_object_list(bundle.request)

Photo via Visual hunt

You Promised Me!

I absolutely love Promises in JavaScript code. As a person who started their programming career in DHTML I’ve seen a ton of new features added over time, but none have seemed as powerful as being able to control the flow of my software.

I want to focus on one aspect of Promises for this post though, exceptions. If a Promise function has an exception thrown, the promise will be rejected with the exception as the value.

Here’s an example:

new Promise(function(resolve, reject) {
  throw new Error('ARGHHH!');
}).catch(function(error) {
  console.log('The error is:', error);
});

What I don’t have to do is to do any try / catch to make sure the exception does not halt my program. Great!

One thing that sometimes slips my memory though is that the implicit catching of errors is only done on the function being executed inside the Promise (the executor), it does not extend to other callbacks that are called by that method.

const fs = require('fs');

new Promise(function(resolve, reject) {
  // Error thrown if the file "post.md" does not exist
  fs.readFile('post.md', function(err, data) {
    if (err) throw err;
  });
}).catch(function(error) {
  console.log('We will never get here.');
});

If the file post.md does not exist, Node will throw an along the lines of: Error: ENOENT: no such file or directory, open 'post.md'. That error will not be caught and your app will have a bad day.

The reason is that the callback executed in the readFile method creates a new context for execution and you have to rely on normal try / catch logic if your intent is for the Promise’s final catch statement to have your error.

const fs = require('fs');

new Promise(function(resolve, reject) {
  fs.readFile('post.md', function(err, data) {
    try {
      // It's now ok to throw an error here.
      // You can also just reject it.
      if (err) throw err;
    } catch (error) {
      // Reject any caught errors.
      reject(error);
    }
  });
}).catch(function(error) {
  console.log('The error is:', error);
});

Hopefully this helps you make sure your code’s flow control is exactly as you intended.


Sign up for our newsletter to learn some more tips and tricks, or just keep up to date on what we’re doing.

If you’d like to teach those tips and tricks to your team, we offer coaching and training opportunities for existing team members at your company.

We’re going to South by Southwest!

Later today I get to board a plane to one of my favorite American cities, Austin, Texas. It’s that time of year for the ridiculously large South by Southwest conference that celebrates all things tech, film, and music.

This trip is a little different though, as I’m going to celebrate one of our clients, iDisclose, being one of the selected startup companies at the SxSw Startup Showcase.

iDisclose robot avatar

I’m extremely happy with the work that we have done to get iDisclose to market over the past year. It is very satisfying to help a client go from idea to execution and then watch them gather the media and industry attention they deserve.

None of this would have been possible without CEO Georgia Quinn though. She’s extremely good at what she does and has made the difficult navigation of crowd funding much easier to navigate. This will even be the first time we get to meet in real life. Google Hangouts have gotten us a long way, but nothing beats being able to high five an amazing client in person.

If anyone else would like to learn more about iDisclose or how we tackled the project, feel free to say hello at SxSw or online.

Cleanup Docker Images and Exited Containers

It’s pretty easy to accumulate Docker containers and images on a development machine. Normally, every container that is ran is preserved on your machine. Try running docker ps -a and see how much you’ve accumulated over time.

Concerned about loss of disk space over time, I found a blog post that talked about cleaning up after Docker. Part of the article talked about removing dangling images, or intermediary images that are created while building other containers.

docker rmi $(docker images -f "dangling=true" -q)

However, I also wanted to clean up exited containers that accumulate from running docker-compose run commands, but leave the containers that are automatically started and stopped from running docker-compose up.

I ended up with the following bash alias to help me retrieve previous disk space:

alias docker-cleanup='docker rm $(docker ps -a -f "name=_run_" -q) && docker rmi $(docker images -f "dangling=true" -q)'

As a bonus, here’s the bash alias I use to quickly connect a terminal session to the default docker-machine.

alias docker-setup='docker-machine start default; eval "$(/usr/local/bin/docker-machine env default)"'

Running Tests Automatically With Watchman

I’m currently working on a very small PHP library for a client and was looking for a way to automatically re-run the test suite anytime a PHP file is updated, added, or deleted.

A similar library on the Ruby side of the fence is called guard, which listens for file events and runs commands in response. I’ve used guard in previous projects, but I try not to pull in dependencies from other programming languages if possible in projects. Also, guard represents something that I’m trying to minimize in my development process which I’ll call a “wrapper application”.

“Wrapper Application”

I’m not sure if there’s a better word for it, but I’m going to talk about “wrapper applications”, or a library that wraps the core functionality that I’m trying to work with. In this case, it’s calling a command in response to a file system change. To get to the library that is actually doing the watching, guard pulls in listen, which pulls in rb-fsevent who does the actual monitoring.

If rb-fsevent makes a breaking change (or fixes a bug, or adds new functionality) I will have to wait for the listen library and the guard library to add the new functionality. I’ve been burnt many times before (I’m looking at you Grunt and Gulp plugins) so I try to minimize wrappers whenever possible. The fewer moving parts, the better.

All of that said, composition of libraries is not a bad thing, just something I like to look out for. Now, back to the story.

Enter the Watchman

When trying to find applications that could fit my need without being a “wrapper”, I ran into two other brew installable apps called fswatch and fsevent_watch, but their cryptic usage instructions and command line arguments led me to find Facebook’s Watchman. It’s open source, been out for a few years, and seemed to be able to meet my needs without requiring a “wrapper” library. In addition, it seemed to be pretty robust.

Installing is pretty straight forward thanks to brew install watchman and the introduction on their website looked straight-forward, but then things went downhill quickly.

The documentation doesn’t give many example setups, so it took a few read throughs before I found how to watch files and trigger commands in response. Unfortunately,
running the test task isn’t very helpful if you never see its output.

Turns out that normally triggered tasks send their output to the watchman log file that’s conveniently buried deep on your system’s bowels. Since I didn’t want to tail a file, I kept poking around in the documentation till I found the watchman-make command. It’s a convenience command that invokes a build tool in response to file changes while sending command output to your terminal. It met my needs and didn’t require any complicated setup of triggers or watchers.

While digging through documentation I also found that watch-project is preferred to the deprecated watch command so that overlapping watch commands can use a common process to be easier on the operating system.

That brings the command needed for my project to:

# Run this command to monitor PHP files and run phpunit in response.
watchman-make -p 'src/**/*.php' 'tests/**/*.php' --make=vendor/bin/phpunit -t tests

It was a bit of a journey to get everything working properly the first time, so hopefully this information will be helpful to others looking for a similar setup.

How to be a Good Developer

I was fortunate enough to be asked to talk to Wadsworth High School students again at today’s High School Career Day. It was a very well organized event and I was proud to be a part of it. I have had quite a few role models that helped shape my personal tech journey and I like to give back when possible.

While last years talk focused on a mixture of entrepreneurship and tech, this year I wanted to talk more about differentiating yourself in an industry that’s attracting more and more people everyday. The following are a few of the topics we covered in case it’s helpful to someone else.

Do What You Love

I’ve found the easiest way for me to learn new things are do to the things that interest me, and constantly learning new things is very important to your development as a developer.

Thankfully my desire to program on the web turned into a pretty good career as well.

An important thing to remember is that at some point in your personal development you will reach a point where you become stuck. The amount of knowledge you have yet to achieve will leave you confused about where to go next. I’ve found that focusing on the things that interest me and not the new and shiny worked quite well. One thing will lead to another in tech, but you should never get discouraged with the expectation that you should learn it all.

Speak Out

I owe a lot of my company’s growth the local special interest groups that I found through sites like meetup.com. I ended up with an entire network of amazingly smart and helpful people that have allowed my business to spread word of mouth.

We grew together, learned together, and helped each other meet our career goals.

For me, giving a talk at meetups led to speaking at conferences which were an excellent way to be viewed as a subject matter expert. You’ll need to back up your words, but if you’re constantly learning new things that’s not a problem.

On the Job Experience

Nothing can beat actual on-the-job experience. I encouraged all attendees to take advantage of co-op / internship programs to find out more about how their desired industries operate in the day to day. Find out if you’ll enjoy programming for the rest of your life as quickly as you can to avoid a costly change down the road.

Outside of working for other companies, you can do things to showcase your aspiration and talent by tinkering on side projects or even contributing to open source development. As you learn more about programming languages, libraries, and frameworks you’ll be introduced to an entire world of opportunities to show off. Take advantage of it.

Finally, feel free to reach out to the company’s you admire and ask if you can learn more about how they work. You may even be able to hang out and shadow them for a day to learn more about what skills they are looking for so you can direct your own personal education.