Category Archives: Uncategorized

STOCK GLASSES – Focused and Simplified Stock Analysis

“Everything should be made as simple as possible, but no simpler.”

-Albert Einstein

I’ve been working on a project to play around with Python and Flask and it snowballed into a full blown web app which I’ve deployed.

The app is called Stock Glasses, and it’s purpose is to provide a tool for focused and simplified stock analysis based on First Principles thinking and concepts in respected financial investing books such as “The Intelligent Investor” by Benjamin Graham and “The Intelligent Asset Allocator” by William Bernstein.

Use the working app here – https://stock-glasses.com

Follow on Twitter: @GlassesStock

Also see the Stock Glasses YouTube Channel for demonstrations of using the app to analyze stocks.

Inspired by First Principles thinking and the quote by Einstein above, the goal is to eliminate noise and focus on the essentials to evaluate a company.  Basically the app focuses on analysis of these fundamentals:

  1. Top Line – Revenue
  2. Bottom Line – Profit/Net Income
  3. Financial Health – Current Assets vs. Total Debt

For a full explanation of how to use the app, visit the How To Use Page of the app.

Future plans for this project include turning it into a progressive web app for offline use and playing around with comparison analysis further.

The app was built with React/Redux, Python Flask and utilizes Firestore for persisting data.

I welcome any feedback, particularly from finance people who might be able to  critique or offer suggestions/improvements on the metrics and analysis tools offered by the app.

Usual disclaimers apply: I’m not a financial advisor or pro investor, so use and invest at your own risk.  I do think it is a potentially useful tool for learning about basic stock analysis, understanding some common metrics and a good introduction to Value Investing.

Additional resources which inspired the app:

 

 

Firestore Security Rules – Protecting User Data

Question: How in the Sam Hill do I restrict access to data in Firestore to only the user who is requesting it?

Answer: Do this.

service cloud.firestore {
  match /databases/{database}/documents {
    match /collectionName1/{userId=**} {     
      allow create, update: if request.auth.uid == request.resource.data.uid;
      allow delete: if request.auth.uid == resource.data.uid
      allow read: if request.auth.uid != null;
    }

    match /collectionName2/{userId=**} {
      allow create, update: if request.auth.uid == request.resource.data.uid;
      allow delete: if request.auth.uid == resource.data.uid
      allow read: if request.auth.uid != null;
    }
  }
}
  • Attach the user id from Firebase Auth(this is what I use for authentication) as a property on the document data you are sending with every request.
  • For the delete rule, check the uid on the resource already stored
  • This is what is used in the rules to verify that the user authorized  is the same user sending items from the frontend.

 

  • A Non-authorized user will not be able to send documents without knowing the user id of the data they are trying to overwrite or update.
  • The read rule will protect against users not logged in with Firebase Auth, however, if a user wants to read items not belonging to them, they would need to know the user id of the other party to access that data (since the data is organized by user under their uid.)

After frustrating hours scouring Stack Overflow and reading the Firebase documentation getting the dreaded Missing or insufficient permissions error, I finally was able to only allow authorized users to access data belonging to them in the Firestore database for a project I’ve been working on.

I am using the built in Firebase Auth feature on the front end (you can find a great video tutorial by The Net Ninja here).

  • Firebase Auth sends the authenticated user id after they’ve logged in with every request to Firebase,
  • You can access the user id token on the request object in the rules using: request.auth.uid
  • Send the user uid from Firebase Auth on the front end with every resource sent to Firestore (in the case of updating, creating, or deleting a document).  You can access this property in the rules on: request.resource.data.[your uid prop here]
  • The read rule is needed in addition separately because you can’t match the auth uid on the request provided by Firebase Auth with any resource property, since no resource is sent with a GET read query.

NOTE: The context of these rules works if the database structure is:

/CollectionName/[UserIdStringMatchingLoggedInUser]/Documents

Just for completeness of example here is an example of a get and create/update query I am making from the front end:

// Attach user uid to the document data you are sending to Firebase:
const data = { myData: "stuff", uid: "[userUidFromFirebaseAuth]" }
export const getSavedData = (uid) => {
  return db.collection(`dataCollection/${uid}/usersData`)
     .get()
     .then(snapshot => {
        const data = snapshot.docs.map(snap => snap.data());
        return data;
    });
};
export const saveData = (data) => {
  return db.collection(`dataCollection/${data.uid}/usersData`)
      .doc(data.name)
      .set(data)
      .then(snapshot => {
          return "Data Saved!";
      })
      .catch(e => {
          console.error("Error saving data", e);
          return "Error saving data";
      });
};

How I Find Clients as a Freelance Web Developer

I’m often asked, “How do you find your clients?”.  This blog post will attempt to answer that question.  The simple answer is, I look anywhere and everywhere all the time.  Freelancing is tough, make no bones about it.  I basically spend all of my time during the day working on client projects and after that, the work isn’t done.   I’d like to share what I’ve learned about how to approach and engage with potential clients, and what has proven to be the most effective strategies and methods for finding clients ‘in the field’.

I’ll first list and illustrate a few ways I try for approaching (or being approached) by potential clients.  The second part of this post will address breaking the ice with people and approaches to conversing with them since this is something that some people find difficult about being a freelancer.  In the final section I will list my conclusions on which methods seem to work best as I have been taking note of my interactions to try to determine what approaches work better than others.

Ways of Searching for and Finding Clients:

1. Bring a web development or programming book with you, wherever you go and put it on the table or counter in front of you so it is visible to others.

I’ve found this so far to be an extremely effective way to open up a dialogue with people.  It’s a great conversation starter.  My book of choice is Refactoring by Martin Fowler.  It has a nice big title (and is a cool word that intrigues people) and is large enough that the book can be seen from a distance.  I’ve taken this book into many different places and even carried it on the street so the title is visible and almost without fail will be approached by others to ask about what I’m reading.  Even bringing it into a cowboy bar downtown, I was approached by multiple people, one of which was a developer with their team and said how happy he was to see someone who knew who Martin Fowler was there.  I wound up handing out 3 cards that night.  Seriously, try this.  The key is that it attracts people who are either interested in technology or interested in people who are interested in technology because…maybe they need a website.

2. Find out if there are large conferences going on in your area, what hotel or area most of the attendees stay at, and make the rounds there.

This is a very effective way to look for clients because usually there will not only be attendees of the conference, but other business owners and representatives there that may need website work.  I’ve found you can strike up a conversation with many people involved in the event if you go to the hotel where most people stay and hang out there.  I recently attended the Stock Show in Denver and it proved to be a great place to meet business owners and people who might need website work done.

3. Go to venues that are related to an interest you have.

I love jazz and hearing live music, and it just so happens that other people do as well.  It may also be in the cards that one of these fellow music lovers may need a website or web development work.  Just by being in a place patronized by other people with a similar interest, I immediately have something in common with everyone there and an easy way to open up a dialogue and conversation which could potentially lead to meeting and working with a client.

4. Go to Meetups

Tech meetups are great for finding potential clients.  Particularly ones that focus on your areas of expertise or ones that are more social in nature than presentational.  I found one client going to a React meetup.  Usually at these meetups there will be a portion of time dedicated to letting people looking for developers make a quick announcement.  In this case, someone was looking for a React developer for their project and we exchanged information and have been collaborating ever since.  Another meetup in the Denver area, Denver Develop Happy Hour, is great for networking and meeting potential clients because it is entirely social in nature – there are no presentations or lectures, just a bunch of people in tech or interested in tech in one place hanging out and socializing.  I met another client looking for a developer for their project at this meetup.  Since I also play drums, I sometimes go to music jam meetups, so if you have another interest (i.e. hiking, painting, books etc.), then it may be worth it to go to those as well to not only meet people with similar interests and make new friends, but potentially meet new future clients.

5. Experimental: Find a venue hosting an open mic and put on a performance

If you can sing at all (or even if you can’t – it doesn’t matter since it’s an open mic and not a professional performance), or if you can do stand up maybe, find an open mic night and perform.  At the end of the  performance, if the owner or event host won’t get too mad, make a quick announcement that you are a web developer and invite anyone that needs help with their website to come talk with you.   This is a recent discovery and method I’m trying and going to keep experimenting with, but after putting on an A cappella performance at an open mic night, I realized that this provides you with the opportunity to essentially have a captive audience of everyone in the room.  Instead of having to make the rounds and find out who might be looking for your services, you can just ask literally everyone there in one fell swoop.

6. Look at Linkedin feeds and social media feeds

One day I just happened to see a post from someone looking for a developer for their project.  This was by accident initially, but now I actively look at social media feeds (especially Linkedin) in case someone posts a request for a developer they need for work.  Reddit also has a ForHire subReddit that is worth checking out.

How to Converse and Engage with Potential Clients:

Note: Some of these principles may be more effective outside of the context of a conference or networking event where the sole purpose is to network and the participants all possess or are looking for a particular skillset.   They might be more useful ‘in the field’ when you are looking for clients outside of the contexts mentioned above in more everyday situations (since as a freelancer, depending on your situation there may be times you have to look for clients more or less every day).  Also, it goes without saying that at some point you need to identify the problem a potential client has and offer ways you will solve it – that is a given and not the focus of this blog post.  The principles outlined below are more about how to start the dialogue with this person at all, which can be a pain-point for some people, and eventually get to that point in the conversation.

Key Principles:

  • Be Patient:  Often, just sitting and enjoying yourself without actively engaging others can work just fine and be a good baseline to operate on.  Good things come to those who wait –  I’ve found that if you are trying too hard to engage potential clients, it can look a little desperate or simply be inappropriate to bother people and so it can wind up turning people off.  Just being patient and observant (see below) and being relaxed makes you more approachable and usually this invites others to open a dialogue or at least doesn’t put them off.

 

  • Be Observant:  This is a sibling to the principle above (Be Patient).  You need to be able to sense when to engage with another person.  Sometimes, people may actually want others to engage with them and you’ll have to read body language and use your intuition to tell this – it can be fairly obvious (they constantly turn to look at you, or make comments out loud to nobody in particular about the venue or what’s playing on the TV).  This is usually an implicit invitation to engage in a dialogue with the person or a sign that they do not wish to be left alone, and you should seize this opportunity.  Make your responses to their comments or glances brief at first to test the waters, and then things should open up from there.  In addition, if you over hear someone nearby speaking about a common interest, then this is also an opportunity to engage in a dialogue about that interest – you’ll have to use your discretion on when to approach them about the subject so as not to interrupt.

 

  • Enjoy the Thrill of Taking a Risk and Exploring the Unknown: It goes without saying that not every conversation or engagement with a potential client will go well.  This should not be something to be feared, but embraced.  You need to enjoy the adventure and thrill of not knowing how things may turn out.  This is exciting – think of it as being like Indiana Jones going into the Temple of Doom (or pick your favorite hero) and daring to embark where others fear to tread dodging all sorts of booby traps and steamrolling boulders along the way.  You are an adventurer, like Lewis and Clark on an expedition to explore the unknown.  Even if there is danger of failure, you have to remember that there is the potential of wild success and the discovery of something great just as well.   I find it helpful to romanticize my excursions to find clients in this way.  For the most part, the worst that happens is an interesting conversation with someone you haven’t met.

 

  • Do Not Make a Pitch Initially or too Quickly: Making the pitch too quickly, or sometimes even at all turns people off and puts them on the defensive; Nobody likes pushy people and most are usually skeptical of salespeople.  I’ve found it much more effective to make having a genuinely enjoyable conversation and developing a genuine interest in the person you’re speaking with your goal, and then at some point along the way as the conversation progresses, usually you’ll wind up asking each other what you do for a living and that can open the door for mentioning your web development services.  They may need a website, or not, and respond accordingly.  If there is not explicit interest, then at least you’ve had an enjoyable conversation, maybe learned something new and you can tell them how much you enjoyed talking with them and casually hand them your card saying if they have any need in the future or know anyone who does, feel free to get in touch.  And they just might…

 

  • Find Topics of Common Interest to Talk About:This could be the kind of music you both enjoy, places you’ve been or traveled to, being curious about where they’ve lived, favorite foods or drinks, etc.  This typically should be the focus of the interaction.

 

  • Be Genuinely Interested in the Person You Are Speaking With:  This is probably the most important fundamental principle and idea to successfully engaging in conversation with others and potential clients.  At the end of the day, people actually are incredibly interesting, each like a complex Symphony with different perspectives and experiences from your own that you can learn from.  People are mind-bogglingly fascinating and realizing this is key to enjoying the process of taking part in and looking forward to opening up a dialogue.

Concrete Examples of Conversations I’ve had while looking for clients:

These are examples of actual conversations I’ve had while making the rounds looking for clients.  My hope is that they provide a real life example of how these dialogues can begin and give a feel for how one can start a connection with someone who may need your services. Some of the details of the conversation have been altered to make the parties involved anonymous.

  • At a venue watching a basketball game involving the Utah Jazz:
Potential Client: "So, who are you rooting for?"
Me who doesn't follow sports:  "The Utah Jazz, just because they have Jazz in their name."
Potential Client: "So you like Jazz?  Me, too.  Where can I go to hear some jazz around here?"
Me: "...[tells him where to go]"

And the conversation evolves from there during which a question of what each other does inevitably comes up.

  • This was during the Stock Show where I met a potential client in the Brown Palace needing work for his website.  He had sat down to order food and while he was waiting for the order to come out he seemed unoccupied and approachable, so I leaned over and asked:
Me:  "Are you involved with the stock show?"  
Potential Client: "Yeah, are you here for it? 
Me: "Yes..."
Potential Client:  "Did you go to the rodeo, you don't look like a rodeo rider... "
Me: "Definitely not.  I've just been checking things out since a couple I met recommended going to the Stock Show.  What are you involved with here?"
Potential Client: "I'm selling [supplies]..."

He then tells me about where he is from and being really curious about the place, I ask about what it’s like to live there and if there is a tech scene.  He tells me about it and then mentions that he has a website he is not quite happy with and might be able to use my help.

  • Again at the Stock Show speaking with an owner of a company that sells medical equipment.

I was sitting at the hotel bar waiting patiently and a gentleman comes up and orders a Scotch.  I thought it would be a good conversation starter if I ordered the same drink and then ask him how he liked that brand of Scotch to confirm that I made a good choice.   This starts a conversation about Scotch and I tell him about Bruichladdich which was recommended to me by a friend from Scotland years ago (just to be clear, I don’t make things up – I really had a Scottish friend recommend that Scotch to me).  He writes it down on a napkin which leads to a discussion about what we’re doing at the Stock Show.  I’ve found that telling people you are directly trying to find clients is not effective and has a similar effect to making a pitch too early.  Instead I tell him that a couple I met recommended I check the Stock Show out (which, again, is true).  We also spoke about where he was from, which was interesting to hear about.  Eventually he asked what I do and I was able to hand him a card at the end of an enjoyable conversation about Scotch and different parts of the country.

Conclusions:

  • Going to Meetups has proven to be a successful activity to engage in to find clients looking for freelance developers.  Don’t expect a hit every time, but persistently attending them could be worthwhile and lead to finding people looking for your skills and hiring you.
  • While the Meetups can be fruitful, going to hotel bars or restaurants where a large convention or conference is being held allows for more opportunity to meet established business owners that may need website work.
  • The most effective strategy for opening up a dialogue with people about Web Development and Programming is taking a book with you and making it visible to others nearby.  This is almost without fail a conversation starter and a great way to break the ice and converse with others who may need website work and could use your services.
  • People don’t like being given a pitch and are skeptical if you come out swinging directly trying to sell your services (this, of course, can depend on the context).  People do like having a good conversation (just like you do) and that should be the focus and goal.  You will find a much more receptive attitude towards you when you bring up web development in the course of the conversation.
  • I’ve found that going out ‘into the field’ and meeting people in person is the best way to find clients as a freelance web developer.   Online freelance sites like Upwork, etc. have proven to be ineffective and not fruitful.  Meeting as many people as you can and getting involved in the local scene seems to be the best way.

Other Resources:

How to Get Socket.io to work with React-Native

After a frustrating couple of days trying to get socket.io to connect to a web socket on my Node/Express server for my project HereHere (place based chat app – please check it out if interested), I finally found out how to make it play nice with React-Native (v0.57).  After reading through numerous posts, GitHub issue threads and blog articles, I thought it would be nice to have one place where you can go to get socket.io working with your React-Native project, so this is just a quick post on how to get it set up and working.

Key points:

  • You need to use socket.io-client on the react-native client side of things
  • The latest version of socket.io-client 2.2.0 does not work with React-Native currently apparently, so you need to install and use version 2.1.1
  • In development, the connection URL on the client side may need to be set to one of three possible values: http://localhost:<serverPort>, http://127.0.0.1:<serverPort>, http://<your IP assigned by your router>:<serverPort>, or if using an Android emulator (I did not need to do this, but it was recommended on a Stack Overflow post, so try it if all else fails) http://10.0.2.2:<serverPort>
  • In production, the connection URL on the client side needs to be pointing to the URL where your server is hosted that handles websocket connections: https://yourserverurl.com
  • Note: I am using Expo to bootstrap my React-Native project.
  • I am also using a Node.js server built with Express on the back end.

Steps:

    1. Install socket.io-client v2.1.1 in your react-native client side project.
      $ npm install [email protected]
    2. In your main App.js file or wherever you would rather initialize socket.io, import the library:
      import socketIO from 'socket.io-client';
    3. Connect to a Web Socket connection to your server by assigning a const to a call to the imported library function and pass in the url to your server (see the possible values in key points above!!) .  Also, pass in some config params, the most important of which is the `transports` key set to `websocket`.
    4. Connect the socket with .connect() and and add a listener to confirm the connection with a console.log.
      Note: initialize socketIO in componentDidMount() in your main App.js file for your React-Native app.  You could extract the code to a module file and call it ‘startSocketIO.js’ to make things cleaner in App.js.

In App.js (your main app component on the client):

import React from 'react';
import { Platform, StatusBar, StyleSheet, View } from 'react-native';
import { startSocketIO } from './services/socketIO';
// ...any other imports needed

export default class App extends React.Component {
  state= {
    isLoadingComplete:false,
  };
componentDidMount() { 
  const socket = socketIO('http://192.168.0.8:5000', {      
  transports: ['websocket'], jsonp: false });   
  socket.connect(); 
  socket.on('connect', () => { 
    console.log('connected to socket server'); 
  }); 
}

// In this case, note that I used the IP address for my machine assigned by the router (in Network Connection details).  This got it working in my development environment.

For further clarity here is an example of some of the code in my Socket IO module where I initialize and use the library.  I export the module to be used in componentDidMount() in my App.js component (top level App component):

 

import socketIO from 'socket.io-client';
...other imports like config file containing Server Url, any secrets, and actions...
// Initialize Socket IO:
const socket = socketIO(config.SERVER_URL, {
  transports: ['websocket'],
  jsonp: false
});

// export the function to connect and use socket IO:
export const startSocketIO = (store) => {
  socket.connect();
  
  socket.on('connect', () => {
    const { userId } = store.getState().user;
  
  socket.on('disconnect', () => {
    console.log('connection to server lost.');
  });
  
  socket.on('newMessage', (message) => {
    store.dispatch(storePublicMessages([ message ]));
  });
};


// In App.js:
import startSocketIO from ...

export default class App extends React.Component {
  componentDidMount() {
    startSocketIO(store);
  }

  render() {
      return (
        <Provider store={store}>
          <View style={styles.container}>  
            <AppNavigator />
          </View>
        </Provider>
      );
    }
  }
}

SETTING UP SOCKETIO IN PRODUCTION:

In order to get it going in Production, you need to pass in the domain URL pointing to where you are hosting your server.  In my case I hosted a Node/Express server on Heroku:

In App.js inside componentDidMount():

const socket = socketIO('https://myserver.onheroku.com', {
  transports: ['websocket'], 
  jsonp: false 
}); 
socket.connect(); 
socket.on('connect', () => { 
  console.log('connected to socket server'); 
});

This was mainly about getting things setup to work on the client side with React-Native, but just for completeness sake, here is a quick snippet of my server.js file which sets up an Express server and socket.io.  Note that on the server side I am using the socket.io library (the latest version) and not socket.io-client.  Also note, that you need to use the builtin https Node module to create a server which you pass the express app into, and then pass that server to socketIO.

Example Main Server file in back end code of the project:

const http = require('http');
const express = require('express');
const socketIO = require('socket.io');
const mongoose = require('mongoose');
const keys = require('./config/keys');
require('./models/Message');

const PORT = process.env.PORT || 5000;
mongoose.connect(keys.mongoURI);

const app = express();
const server = http.createServer(app);

const io = socketIO(server);
io.on('connection', socket => {
  console.log('client connected on websocket');
});

server.listen(PORT, () => {
  console.log('server started and listening on port ' + PORT);
});

Hopefully, this will save you some headache and time pouring through Stack Overflow and posts trying to figure out why your socket IO connection is not working in React-Native.  If you have any questions, comments or suggestions feel free to post them in the comments section and I’ll help with whatever I can.

CLEAN CODE IN A NUTSHELL

What is clean code?  How do you write clean code?  I will attempt to address these questions in this “In a Nutshell” series blog post.

Clean Code In a Nutshell:

  • The crux of it is: Clean code is code that is written in a way that is easily understandable, readable and maintainable by other Humans.
  • Key aspects of clean code:
  1. It is DRY (does not repeat unnecessarily)
  2. Concise (but not too concise!)
  3. Tells a story to the reader in a logical sequence about what is happening in the code
  4. Incorporates the SRP principle and Separation of Concerns
  5. Is easily maintainable (modular) and does not make the person who is reading and working on it want to pull their hair out

That’s basically what it means to write clean code.  For further explanation and examples, continue reading…

Definitions:

  • Code Smell: This refers to code that is not clean and “smells”.  There is something about the code that is unnecessarily confusing, unclear or something that could be improved upon to make it cleaner.
  • DRY: The “Don’t Repeat Yourself” principle.  The goal is to eliminate as much repetition of code as possible and re-use as much code as possible, which keeps things less cluttered and clean.
  • SRP: The “Single Responsibility” principle.  A method, object or class should do one thing and do it very well.  This makes things easier to maintain and keeps things de-coupled.
  • Separation Of Concerns: Code should be logically grouped based on what operations it is performing or data it is related to.  Methods in classes and objects should be closely related to each other and separated.
  • Spaghetti Code: This is code that is not separated logically and is not modular.  It is very difficult to maintain and understand and is usually heavily coupled (the code is connected to and affects many other parts and operations in the application) so that changing one line may have unforeseen side effects on all sorts of other parts of the code base.  It is a nightmare to deal with and the opposite of clean code.

METHODS FOR WRITING CLEAN CODE (and what to avoid doing):

 

NAMING VARIABLES:

  • Names for variables should not be ambiguous, but be descriptive and meaningful.
  • Magic Numbers and Magic Strings: Strings or Numbers usually used as variable names which do not indicate to the reader of the code what their purpose, origin or use is related to.  Don’t do this.  Always make variable names descriptive and meaningful so it’s clear to the reader what they are for and doing.
  • Make naming formats consistent.  If related variables are in camel case, then make sure all of them are in camel case, or if there is a word that is appended or prepended to related variables, make sure you keep using that format.
  • Follow naming conventions in whatever language or framework you are using.  For example, in C# the names of classes, it’s properties and methods use Pascal Case while private fields, method parameters(arguments) and local variables use Camel Case.  In React, all component names and classes should have the first letter capitalized.
  • Try not to use names that are too long or hard to read.  Keep them short (but not too short).

Examples:

// Avoid: Ambiguous variable names:
const x = "Please log in.";
// Cleaner:
const loginMessage = "Please log in.";

// Avoid: Magic Numbers and Strings:
if (userStatus === 1) {
  return true;
}
// Cleaner:
const loggedIn = 1; 
if (userStatus === loggedIn) {
  return true;
}

// Avoid: inconsistent naming:
const username = "Brent";
const user_profile = false;
// Cleaner:
const userName = "Brent";
const userProfile = false;

// Avoid: really long and hard to read names:
const loginUserAndFetchDataFromDatabaseAndUpdateTheReduxStore =  () => { ...code );
};
// Cleaner: use the SRP and Separation of Concerns principles: 
const loginUser = () => { ...code };
const fetchUserData = () => { ...code };
const updateStore = () => { ...code };

METHODS, OBJECTS, CLASSES (SRP and Separation of Concerns):

  • Keep methods short and have them do only one thing!  Methods should do one thing and do it very well (have a single responsibility).  There are differing opinions on how long methods should be, but the goal is to make them as short and as contained as possible.  Some say they should not be more than 10 lines of code.   Just try to make them as short as possible without making the code hard to understand.
  • If methods get too long, look for ways to extract parts of the code to a separate object or function that you use inside the method.
  • Cohesion Principle: All code that is related closely should be together and code that is not should be separated.  Objects and classes should contain data and methods that relate to each other and only have to do with the data or operation that the object/class is concerned with (Separation of Concerns).
  • The Information Expert Principle (or similarly the Encapsulation principle) states that a method should be attached to the class or object that has the related data which it uses (similar to the Cohesion Principle).
  • The number of parameters should not exceed three.   You can extract parameters and batch them in objects or encapsulate them to reduce the number of arguments.  If possible, also avoid using booleans as parameters.
  • Variables should be declared as close as possible to where they are being used so the reader does not have to search around to find where they are defined.

Examples:

// Avoid: long methods and functions with too many parameters and doing more than one thing...
function fetchUserDataAndLoginUser(loggedIn, userId, db, userProfile, userPassword) {
  let userData = {};
  if (!user.loggedIn) {
     ... 
     lots of code to login user on the back end
     ...
     ...
     ...
     userData = db.find({ user: user.id });
     ... 
     lots of code to load userData into a profile view
     ...
     ...
  } else {
 window.location.replace("https://site.com/dashboard"
);
  }
}

// Cleaner (separate the operations into separate functions to use and combine the arguments into a single encapsulated object):

const user = {
   userId,
   userProfile,
   userPassword,
   loggedIn 
};

function authenticateUser(user) {
  ...code for checking passwords and authenticating the user.
}

function fetchUserData(userId, db) {
  ...code for fetching authenticated user data from the database
}

function renderUserData(userData) {
  ...code to render the userData on the view.
}

authenticateUser(user, db)
  .then(user => {
    fetchUserData(user.id, db);
  })
  .then(userData => {
    renderUserData(userData);
  });

// Note how the code now tells a story in a logical succession to the reader and each method only deals with one thing and part of the process separately.  The user is logged in and authenticated, then their data is fetched from the database, and then the data is rendered to the view.  
// The code is also easier to maintain because if there is a point of failure along the way, the developer can look in the appropriate method dealing with the failing operation and pinpoint and debug quickly and easily which step is failing.

CONDITIONALS (IF/ELSE STATEMENTS):

  • Keep conditional statements as flat and easy to understand as possible by using refactoring techniques and avoiding common pitfalls.
  • A Nested Conditional is an if/else statement contained within another if/else statement.  Avoid them: they are difficult to read, understand and test.
  • There are circumstances in which nested conditionals can be refactored by considering the relationship of the conditional parameters between the statements.  (See examples below).

Examples and ways of refactoring conditionals:

Use a Ternary Operator:

// Not nested, but easily refactored to make the code cleaner and more readable:
  if (user.id) {
    userLoggedIn = true;
  } else {
    userLoggedIn = false;
  }
// Cleaner:
userLoggedIn = user.id ? true : false;

// NOTE: Never combine ternary expressions and only use one - multiple ternary expressions are too difficult to understand and read.

If the statement sets a Boolean to a variable based on the condition, you can simplify it by setting the variable to the condition in a single line eliminating the if/else statement:

// Avoid: Unnecessary if/else statement:
if (userLoggedIn) {
  showProfile = true;
} else {
  showProfile = false;
}
// Cleaner: showProfile is simply dependent on the value in the condition...it can be refactored to:
showProfile = userLoggedIn; 

Watch out for nested if statements that a single block is based on. Use the && operator or early exit technique to refactor:

// Avoid: nested if statement inside a single block:
if (user) {
  if (user.id) {
    ...code
  }
}
// Cleaner: refactor using the && operator to eliminate the nested if statement:
if (user && user.id) { ...code } 

// Or use the early exit technique to return if a or b is not true to eliminate nesting:
function verifyUser(user) {
  if (!user || !user.id) {
    return;
  }
  ...code to run if user and user.id are true
}

Refactor nested if statements that have repeated conditions to combine them with logical operators:

// Avoid: Nested conditionals with identical conditions:
if (userIsGoldMember) {
  if(itemsInCart) {
    applyDiscount = true;
  }
}
if (totalCost > 100) {
  if (itemsInCart) {
    applyDiscount = true;
  }
} 
// Cleaner: combine the identical conditions and variant conditions with logical operators to eliminate the nested conditional:
applyDiscount = (itemsInCart && (totalCost > 100 || userIsGoldMember));

Make conditions more expressive by extracting the condition to return a boolean in a separate function:

// Avoid: conditions that are complicated and not easy to read quickly:
if (Date.now() >= (new Date(2018, 11, 25).getTime() + 24 * 60 * 60 * 1000)) {
  ...code
}

// Cleaner: separate the condition into a function that returns true or false and describes what the condition is clearly:
const dateIsAfterChristmas = () => {
  return (Date.now() >= (new Date(2018, 11, 25).getTime() + 24 * 60 * 60 * 1000))
};

if (dateIsAfterChristmas()) {
  ...code
}

Refactor Triplicate conditionals: A triplicate occurs when one of multiple conditions is required.  Use the || operator instead of if statements:

// Avoid: separate if conditionals for a triplicate:
if (condition1) {
  return true;
}
if (condition2) {
  return true;
}
if (condition3) {
  return true;
}
return false;

// Cleaner: use the || operator:
return condition1 || condition2 || condition3;

COMMENTS:

  • Comments should not be redundant or stating what is obvious in the code – it just makes more clutter in the code base.
  • Ideally, you shouldn’t need comments since the code you are writing tells a story and it is clear and easy to understand what is going on.  There are differing opinions on this and I think it is a good rule of thumb to follow most of the time.  In reality, there may be a situation where comments would be very helpful to the reader (i.e. when the code is written in an unintuitive way that is necessary, and refactoring would cause breaking changes).
  • If you need to write a comment, don’t write comments addressing “whats” (what the code is ‘saying’, so to speak), write comments that address “whys” and “hows” (why this code is the way it is or how it is doing some operation).
  • Minimizing comments is also a good idea because developers may change logic in the code base, but not update the comments which can cause confusion in the future.
  • The exception to leaving out comments is the case of making a `TODO` note;  These are good comments when a problem in the code is found and a note needs to be left for an issue that needs to be fixed and addressed.
  • If you see comments for blocks of code describing operations in a method, that is a sign that it should be refactored and the operations should be extracted into separate methods.

FURTHER READING AND RESOURCES: 

FULL VERSION (PROTOTYPE) OF COMMENTS EXPLORER DEPLOYED

I have decided to release a prototype of the full version of my Comments Explorer app to get feedback and suggestions.

Click Here to Try the Full Version of Comments Explorer.

Features:

  • Pull a comments list from a Youtube video and search the list by author or text for keywords or phrases.
  • Filter the list of comments by date, thread, or like count.
  • Save comments to your dashboard for future reference or processing.
  • Google OAuth sign-in for easy access.

Built with React, Redux, Material-UI, Node/Express, PostgreSQL, Knex.js including Stripe payment system integration and consumes the Youtube Data API.

The purpose of this app is to provide Youtube content creators or small business owners with videos on Youtube with an easy way to manage their comments section and organize comments that need to be addressed or removed.  The idea is to help video owners to more effectively process and deal with comments on their videos – whether this means being aware of customer or viewer complaints and suggestions, or monitoring unwanted or inappropriate spam or vulgar entries.

The full version adds on to the basic search and sort functionality of the demo by allowing users to save comments to their dashboard, and create custom categories to act as folders to store and organize comments.  Comments can be moved from folder to folder and deleted as desired.

I’ve also integrated the Stripe payment system to the app which is currently in test mode since I’m awaiting approval by Youtube to commercialize the app.  In the meantime you can access the paid version of the app by clicking on Access Full Features in the header and selecting a plan.  On the payment form simply enter 4242 4242 4242 4242 for the credit card number and any numbers for the rest of the fields (expiration date must be in the future).   This will take you to your dashboard where you can access saved items and see information about your account and current subscription.

Note that some features such as saved searches in the dashboard are still under construction and not complete.  This is a trial run and the app is finished enough to present it to the public to get feedback.

Features that I’m working on adding are:

  • Ability to mark comments as spam if you are the owner of the video for the comments pulled.
  • Ability to add notes to comments or mark them as addressed or replied to.
  • Automatic emails to users who subscribe to confirm their purchase and distribute receipts for payments.

Again, I’d love to hear what you think, so please leave feedback or things that you would like to see in the app that would make it better.  In the meantime, enjoy using it and exploring the depths of the Youtube video comment sections.

Comments Explorer Overview

I’m excited to have just deployed a working demo of a React app I’ve been developing which allows users to pull comments from Youtube videos and search them by text/author/date/like count.

Click HERE for the Prototype Full Version.

How to use the app:

Just find a Youtube video you have an interest in exploring the comments section of, and copy and paste the URL into the form field on the landing page.  Click the Display Comments button and you’ll be presented with a list you can search through using the filters at the top of the page.  If you want to reply to or edit and delete your own comments, just log in with Google by clicking the button in the top header of the page.

The reason for the App:

I was always frustrated when reading through comments on Youtube videos to see if a question I had about the video topic had been addressed by somebody already.  Since the comments are loaded as you scroll down the page, you can’t just hit CTRL-F and search for what you’re looking for without sitting there for a long time scrolling and scrolling.  With this app, pages of comments are downloaded and searchable by text, date, author and sort-able by like count and newest/oldest making it easy to search for comments that match what you’re trying to find.

Use Cases:

  • Social Media Managing Tool: Monitoring and exploring comments for videos in an easy to use GUI (Graphical User Interface) for small businesses or content creators.
  • Researching a particular topic of interest and seeing what other people  have to say about it in the comments section.  For instance, if someone is interested in a phone or laptop, they could search the comments for “battery” or “good tips”, etc.  This could be for any topic such as a video on a hiking trail, investment related videos and whatever else you can find on Youtube that is of interest.  The possibilities for research and discovery by scouring the depths of the comments section was the original inspiration for creating this app.
  • Finding new ideas for insults or names to hurl at other people.  The comments section can be a very useful resource for this.

Main Features:

  • Search a list of comments for a video by text (phrase or keyword) or by author. 
  • Respond and reply to comments found in search results through the app Interface easily by logging in with Google.
  • Delete or edit comments of which you are the author after logging in with Google.
  • Sort comments by date, like count, thread or spread out individually.

Features in the full version:

  • Dashboard for managing saved comments and previous searches with the ability to organize saved items in category folders (i.e. you could have a “Customer Complaints” folder or a “Response Complete” folder for managing comments posted by customers and viewers).
  • Retrieve up to 40 pages of comments (would equate to potentially 4,000+ comments) for searching, exploring and managing comments on videos of interest.  The demo currently only allows a search limit of 5 pages of comments (~500 comments).
  • Easily Mark comments as spam or remove them from your video comments page as a content creator.

Example of a list of comments on the results page with search filters, etc:

Tools and Technologies Used:

The app consumes the Youtube DATA REST API and is currently awaiting approval for commercialization from Youtube.  It was built with React using Redux, Node.js with Express, PostgreSQL using Knex.js as the ORM.

I hope you find this app useful and fun to use and I would love to hear any feedback or suggestions from anyone who uses the app.

JavaScript Quirks In a Nutshell

When I was first learning JavaScript I would come across posts about how weird (or bad) the language was, and since it was the first programming language I learned and didn’t have anything else to compare it with, I didn’t understand why some people had a negative opinion of the language.

This is an attempt to assemble  a list of those JavaScript quirks that give it a bad wrap, and were confusing to me when I was learning, as well as key concepts that are vital to understand in order to write good (i.e. working) JavaScript code.  My goal is to create a concise list that would be helpful for those learning the language to reference in order to understand some of the “weird” behavior of JavaScript, and how to use the language more effectively while not having to learn these things “the hard way”, or learning them way too late.  The list is meant to be an overview to make the student aware of these things and serve as a launching point for further exploration and research.

NOTE: This list is a work in progress and constantly expanding.  It will be updated and is under construction, so if there are other quirks or important concepts that you would like to see included that would help one write more informed and well-written JavaScript code, drop a note in the comments section.  It would be great to have a one stop shop that has as many of the quirks and confusing things about JavaScript in one place for people who are learning to have as a reference.

Table of Contents:

  • …more to come

THE CREATION AND EXECUTION PHASE:

  • When the JavaScript Engine runs in the browser, it runs in two phases – a Creation Phase and an Execution Phase.
  • A Creation Phase and Execution Phase is run every time the JavaScript for the app initially loads to create the Global Execution Context, and also runs for each successive call to any function to create that function’s Execution Context.
Terms:
  • Creation Phase:  All variable names (including the built-in this variable), objects and functions are created and stored in memory for use in the Execution Phase.  For example, on an app initialization (first load), the global window object is created and variable names, as well as functions in the code are created, stored in memory space and attached to the global window object.  A Global Execution Context is created and the this keyword is created and setup.  In addition, an outer reference to the immediately outer Execution Context is set up which allows access to variables and objects in that context (In this case there wouldn’t be an outer context, since the global context is the top most level).
  • Execution Phase:  The JavaScript code is then run and executed, line by line, without stopping or pausing.
  • Execution Context:  The environment that is created during the Creation Phase that the JavaScript code runs inside of during the Execution Phase.  It defines the variables, objects, functions and function arguments which are available and accessible, as well as the scope chain, and the this value.

*A new Execution Context is created for every function that runs in JavaScript which entails running through a Creation and Execution Phase for it, and setting up an outer reference to the immediately surrounding Execution Context which allows access to the outer context’s variables and objects (see Scope Chain below for more details). 

  • Execution Stack:  A model or data structure in the JavaScript engine which keeps track of the order of the execution of code and it’s current Execution Context.  Every time a function is called in the code, a new Execution Context (or Call Stack) is created and placed at the top of the Stack.  JavaScript is a single threaded language (which means it runs one call stack at a time).  When the execution of the function is completed, that Execution Context is “popped” (removed) off the top of the Stack, and the code of the previous Execution Context on the Stack beneath it is run, picking up from where it left off from before the code from the popped Execution Context began running.  (Further resources: see this great Youtube video lecture on the Call Stack and the Event Loop)

HOISTING:

  • Refers to the storing of functions and variables in memory by the JavaScript engine during the Creation Phase (see above) before the code actually runs.   All variables are initially stored and set to a value of ‘undefined’, but all functions are stored complete in memory (including the declaration of their name as an identifier for a space in memory to look, and their value (the body of the function, etc.)).
  • This is why you can define a function in your code AFTER you actually call it, but variables will return undefined if they are referenced before their declaration in the code.

Example:

// Calling the function in the code before it's defined:
hoistedFunction();

hoistedFunction() {
  console.log("The function ran and worked!");   
}

In the above Example, the call to hoistedFunction() will log "The function ran and worked!" even though it is called before it is defined.  This is because during the Creation Phase, all functions defined in the code are “hoisted” into memory and made available before the code actually is run in the Execution Phase.  Note that this is different from variables, which are initially set to undefined and cannot be referenced before they are assigned in the code.


THE SCOPE CHAIN:

  • If a variable is used in a function and a value is not found for it inside that function’s scope or block, then JavaScript will look for it’s value in the function’s outer environment context.  If the value is not found there, then it will search the environment of the next outer context, and keep going all the way to the global environment to look for the value for the variable.
  • It should be noted that looking for an outer scoped variable’s value stops when the first match is found.
  • It’s possible to access a variable directly on the global scope with window.[variable name].
  • Lexical Scope:  Scope that is assigned based on where variable and function declarations are written in the code (i.e. functions written inside other function body blocks, variables declared in the global space outside of any function blocks, or inside a function’s scope because they are declared in the body, etc.).

Example of traversing the scope chain:

// a variable created at the top level execution context (global):
const globalVar = "from top level";
// Execution Context is created for initial function:
const exampleFunction = function() {
  const outerVar = "from outer context.";
   // A new Execution Context is created when this inner function runs, but it has access to the immediate outer context it's created in, and also the outer context of it's outer context up the scope chain to the top global level, etc.:
  (function() {
    console.log(outerVar); 
    console.log(globalVar);   
  })();
}

exampleFunction();
// When called, the function logs "from outer context" and then "from top level" - the JS Engine went up the scope chain to find outerVar and globalVar and look for it's value all the way up to the top level global context since they were not defined and assigned a value in the inner function block.

*NOTE THIS QUIRK:  When not in strict mode (‘use strict’), if a variable is not declared with var/let/const but assigned a value, then a variable of that name will be automatically created and implicitly declared in the global scope.

Example:

undeclared = 5;

// A global variable undeclared is created and assigned the value of 5 automatically by JavaScript.
NOTE: If 'use strict' is implemented, then a ReferenceError will be thrown and automatic declaration will not occur.

eval():

  • Built in function in JavaScript that takes a string as an argument, and treats the contents of the string as code that was authored code at that point in the program, consequently altering the corresponding Lexical Scope.
  • Can be used to execute dynamically created code (that’s not
    hard coded initially).
    In other words, you can dynamically generate code that is not hard coded at author time and eval() will inject it as if it were hard coded at author time – this is a way to cheat Lexical Scope (code that is scoped based on where it was authored), but has performance issues and is bad practice.
  •  If a string of code that eval(..) executes contains variable or function declarations, the existing lexical scope in which the eval(..) resides will be modified.
  • Note from reference book listed below: “The use-cases for dynamically generating code inside your program are incredibly rare, as the performance degradations are almost never worth the capability.”

Reference: You Don’t Know JS: Scope & Closures, Chaper 2.


PRIMITIVE TYPES:

Terms:
  • Type:  A category identifier for a piece of data which can be used by the JavaScript engine to determine how to handle the piece of data and what operations can be performed with it. For example, a Number type is assigned to a piece of data that is represented by an integer.  Since the data has a type of Number, JavaScript knows that it can do things like arithmetic with it and another piece of data of the same type, etc.
  • Primitive Type:  Represents a single value in JavaScript that is not an Object type.  (Everything in JavaScript is either a Primitive or an Object).
  • DYNAMIC TYPING:   JavaScript is a dynamically typed language.  The engine figures out and determines what type of data a variable holds (without having to declare it explicitly) while the code is running.  It’s possible for a variable to hold different types of values while the code is running.  You don’t specify what type of data is in a variable (you just use var/const/let, and JavaScript figures out what it is – a Number, Boolean, String, etc.).

6 Primitive Types:

  • Undefined: lack of existence (don’t use this or set variables to this)
  • Null: lack of existence – use this to set variables to nothing (let the engine use undefined). Null is not coerced by JS to 0 for comparisons, but coerced to 0 in other contexts (i.e. with Number() function).

*What is the difference between NULL and UNDEFINED?

null is read by JavaScript to mean that there is no value, but the developer intends it that way and set it to null explicitly (i.e. let x = null;), whereas undefined may throw an error as being an unintended absence of value from not assigning anything to the variable (i.e. let x;), and then accessing it (i.e. console.log(x); ), or by simply not declaring it at all in the first place.  Setting a value to undefined explicitly is not considered good practice.  If you want a value to be assigned as undefined or empty, then set it to null in the code.

  • Boolean:  A primitive that has a value of true or false.
  • Number:  An Integer or floating point number (decimal), i.e. 5 or 5.23 etc.
  • String:  Sequence of characters inside quotes (single or double).
  • Symbol (used in ES6 ):  May not be supported by some browsers.

THE EVENT LOOP:

Terms:
  • Event Loop:  A constantly running process that checks a Task Queue for any callbacks registered which are associated with asynchronous operations or Event Listeners, and pushes them to the Execution Stack whenever it is empty.
  • Task Queue: A built-in feature of the Event Loop that keeps track of and stores registered callbacks for any asynchronous operatons (network requests for example) or Event Listeners (for a ‘click’ Event when a user clicks a specified button for example) which are ready to be run and awaiting a push to the Call Stack from the Event Loop.
  • Web API:  Features and methods that come built-in from the browser and that are provided and made accessible to the JavaScript Runtime Engine  so you can access them in your JavaScript code.  Examples are multi-threaded operations made available by Web API methods such as setTimeout() or AJAX requests over the wire using the XHR (XmlHttpRequest) Object provided by the browser.  Javascript is a single-threaded language, so these features and methods allow access to additional threads which can be used to perform longer-running operations while not blocking the running of JavaScript code.
  • Thread:  A line (or “thread”) of instructions sent to a processor from an application. The set of instructions can be abandoned and come back to later where the processor left off with them last and then complete them (called context switching).
  • Execution Stack (aka Call Stack, or just Stack):  see Creation and Execution Phase entry above).
  • Callback:  a function that is registered to run when an asynchronous operation completes.  These are collected in the Task Queue, which the Event Loop constantly checks to push them to the Stack to run.
  • Event Listener:  A feature which can be accessed in JavaScript code with [element].addEventListener([event], [callback]) that registers a callback function to be run when a specified event occurs.  The browser throws events that can occur which are associated with HTML elements in the DOM as the user interacts with the application (i.e. a ‘click’ event is thrown by the browser when a user clicks on a button element on the page).  The callback registered is then pushed to the Task Queue when the event occurs and the Event Loop will see it and run the callback.

What the Event Loop does:  It’s job is to look at the Task Qeue and the Execution Stack in the JavaScript Runtime and if the Stack is empty, and there is anything (i.e. any callbacks registered) in the Task Queue, then it pushes that callback function to the Execution Stack for JavaScript to run it.


CLOSURES:

  • A closure is a feature of JavaScript which enables a function that is called outside of the scope it was created in (and after that scope’s execution context is cleared from the Stack) to have access to variables and values that were created in it’s original lexical scope (the function block where it was defined).
  • Basically, it’s an encapsulation of values and variables from a scope where a function was defined, so that when that function is passed as a value and called outside of that scope (i.e. returned and used elsewhere in the code), those variables and values remain accessible to it and their values in tact and defined as they were in the original scope.
  • Closures are a commonly used feature whenever you want to pass functions as values to be called at a later time in the code which maintain references to variables in the scope they were created in, and are also used in creating JavaScript Modules, for example, where you can expose methods on a returned object that have references to private, protected, internally defined and scoped variables by invoking a wrapper function which creates a closure, encapsulating those variable values which the exported object methods can reference.
  • IIFE’s (Immediately Invoked Function Expressions) can be used to create a scope and consequently a closure (this can be useful in a for loop, for example to capture the value of i).

Example Use Case with Asynchronous operation in a for loop using a Closure to capture the value of i:

for (var i = 0; i <= 5; i++) {
   (function(i) {
      fetch(`/page${i}`)
        .then(() => {
           console.log(`fetched page ${i}`);
        });
   })(i);
}
// The value of i will be encapsulated by the IIFE on each loop iteration and a reference maintained to it in the asynchronous callback (otherwise the value of i would always be the terminal value since the async function callback runs after the loop is finished and references the value of i at that time.

REVEALING MODULE PATTERN Use Case:

function userModule() {
   const username = "Brent";
   const eyeColor = "brown";

  function username() {
   console.log( username );
  }

  function eyeColor() {
    console.log( eyeColor );
  }

  return {
   username: username,
   eyeColor: eyeColor
  };
}
// Invoke the function to create a closure:
const user = userModule();

user.username(); // "Brent"
user.eyeColor(); // "brown"

// The userModule invocation exposes functions in that module that utilize closures to retain references to private protected variables and values which can be accessed when the exposed functions are called outside of the context they were defined in.

‘USE STRICT’:

  • By typing 'use strict;' in your code, this changes JavaScript’s un-opinionated, loose rules and flexible behavior by preventing type coercion and requiring more explicit syntax.
  • Considered good practice to implement in production code in order to catch potential errors.

Examples of behavior with ‘use strict’:

'use strict'; 

a = 1; // throws an error since var, let, const is not used to declare it. 

17 = '17'; // will throw an error since type coercion is turned off and the string '17' will not be converted to a number or vice versa.

// When calling a function the shorthand way (instead of using fn.call()), this is set to undefined in strict mode:

fn("arg"); // this is undefined.

// Normally when not using strict mode, this is set to the window object in a shorthand function call.
// See this article recommended by Dan Abramov:
Understanding Javascript Invocation and "this" by Yehuda Katz

MISC:

  • Everything in JavaScript is an Object or Primitive data type.
  • JavaScript compiles (translates the human readable code to machine code that the computer can understand and execute) just before execution, as opposed to other languages which are compiled well before.

External Resources/Further Reading:

  • You Don’t Know JS: Up & Going by Kyle Simpson – an excellent book series on Javascript to gain a more sophisticated understanding of how the language works – but written in a way that’s not to dense or difficult to digest.  E-book format is free to read online.
  • wtfjs.com – Funny website with many examples of strange JavaScript behavior.
  • Good article on Scope and THIS – from Digital Web Magazine by Mike West.

 

…More Items Coming… This list will continue to be updated.

Items planned for future updates:

  • Type Coercion
  • truthy and falsy concept and rules
  • Logical Operators
  • Comparisons
  • This keyword
  • New keyword
  • Prototypal Inheritance
  • The Prototype Chain
  • ES6 Classes
  • Promises
  • Synchronous vs. Asynchronous execution
  • Web APIs that add features and asynchronous functionality to JavaScript

Off The Beaten Path: Elm

While attending a meetup in the Boulder, Colorado area (Fullstack Boulder Group on Meetup.com, I had a very interesting discussion with one of the attendees who worked at a local startup.  He introduced me to a programming language called Elm, which is relatively new from what I understand and popular among a small group of developers currently, but that could change in the future.

The most interesting feature he showed me (I’m sure there are many others) was the maybe keyword (see docs here).  This allows the programmer to indicate that an assigned value to a variable could be an expected data type or Nothing (in other words undefined).   This enables flexibility in the code without having to add conditionals to  check if a value or property is not defined.  It enables cleaner, shorter code which is always desirable.

Both of us wondered why a feature like this isn’t implemented in Javascript already, and also speculated that, perhaps in future versions, we might be able to enjoy implementing this flexible option for assigning variable and property values.

I really enjoyed my conversation about Elm and discovering a new and (for now) obscure and not widely used programming language.  If you are in the Denver/Boulder area, there is a meetup you can go to if you want to learn more about the language and hangout with a small, but passionate group of programmers who like the new language.  I love getting off the beaten path and exploring what else is out there, and this is a perfect example of some of the interesting things you can discover when you are open to new ideas and options.

In addition to opening my eyes to Elm, my new friend also turned me on to Reason, which is a new tool created by Facebook that allows programming in OCaml with a Javascript like syntax.  I don’t know much about it yet, but he was very enthusiastic about it and based on what he was able to show me about Elm, I suspect that if he is excited about Reason, then there is a good reason for it.  The fact that it is released by Facebook is noteworthy and it is something that I am going to be putting on my radar.

I love talking to interesting people who I can learn from and open my mind to new ideas.  I plan on continuing my exploration of Elm and look forward to learning more from and other users of the language.  I also look forward to continuing my exploration of the unknown (granted, mostly to me), and to boldly (or, at least eagerly with genuine curiosity) go where, perhaps, not a majority of other people have gone before.

 

PIC BROWSER APP IS ONLINE

I’ve just finished creating a demo version of my Pic Browser App!

Click Here to Try It Out.

Click Here For the GitHub Link with Code samples.

Feature List:

  • User Can Upload Photos into a Collection and Easily Search for a Photo by Caption Description or Filename
  • Instant Search Results via Ajax When Search Terms Entered
  • Gallery Display of Uploaded Photos
  • Edit Photo Collection: Update Captions or Delete Photos
  • Account Registration
  • User Login and Logout
  • Forgot Password Email and Reset Password

Background and Overview of App Functionality:

I got the idea for the app when a friend of mine was trying to show me a photo on Facebook and couldn’t find it in his collections and albums.  There didn’t seem to be an obvious way to search for the specific photo on Facebook, so he gave up and was never able find it and show me.  Since my goal is to create applications that are helpful and useful to people, that prompted me to begin working on an app where users could easily upload a library of photos and find any photo in their collection to show someone or look up for themselves.

The way the app works is users can log in or create an account, and then upload their photos which are displayed by default on a gallery page.

 

During uploading, the user can enter a caption description for the photo which is then stored in the database.  When the user wants to  find a specific pic, they simply type in any descriptive keywords that might match the description they entered for it and if a match is found, the matching pics are instantly displayed on the gallery page via Ajax.

Features to be added in future versions:

  • Photo Albums
  • User Profiles

The demo version lasts 30 minutes and users have access to all features currently implemented.  I hope you enjoy using the app and please feel free to let me know if this is something that you would use regularly and find useful – any feedback is welcome!