Monday, June 11, 2018

Why Javascript objects are powerful


This post discusses some features and uses for Javascript objects that make them one of the most powerful features of the language.


Named parameters

Named parameters is a very neat feature that a lot of newer languages has and it's indeed more readable than position-based parameter list.

Javascript has no direct support for named parameters, but luckily the object destructuring syntax can come in handy here; here's an example

function say({message, shouldScream}) {
    return shouldScream? message.toUpperCase(): message;
}

// Usage
say({message: "cats are awesome", shouldScream: true});

This is much more readable than

say("cats are awesome", true);

and with more than two parameters, it gets really more obvious.

With this, it will be way easier to leave some of the arguments out without having to fill in the gaps with undefineds and also it will be possible re-order them because you're just passing objects around.

Also you can add defaults to them

function say({message, shouldScream = true}) {
    return shouldScream? message.toUpperCase(): message;
}

// Same result
say({message: "cats are awesome"});

These default values can also be used to validate the input by assigning them to functions that throw when the value is missing or not valid.


Easy to create

Objects in Javascript can be created just out of nowhere, with the object literal {} or Object.create method.


Easy to compose

Objects in Javascript are really easy to compose into new objects with compound capabilities

const canFly = {canFly: true};
const canWalk = {canWalk: true};

const chicken = Object.assign({name: "Ken Chic"}, canWalk);
const Pigeon = Object.assign({name: "Eon Pig"}, canFly, canWalk);


Return multiple values

Objects can be used with a function's return statement to return multiple values

function updateCat({catId, props}) {
    // update cat in database...
    return {
        isUpserted: updatedCat.isUpserted,
        updatedCat: updatedCat.result
    }
}


Can be used as other data structures

Objects in Javascript can be used as hash maps or enums for fast lookup times. Their syntax make them really natural to read and write for these use cases.

const config = {MAX_LENGTH: 200};

You can make them a little more faster by creating objects without a prototype so there's no time spent traversing the prototype chain if the value is not found.

const config = Object.create(null);
config.MAX_LENGTH = 200;

Although most of the time you won't need this optimization, and we now have the Map objects designed specifically for this.

You can also loop through them with the handy for .. in statement.


Makes it easy to extract the props you need

When you need to extract a subset of the properties of an object, again the destructuring syntax makes it a lot easier to do that.

const {name, age, funny} = person;

If the property is not in the object, it will have an undefined value, you can add default values to make sure they will always have a value.

const {name, age, funny = true} = person;


That's it. If you have other ideas please share them in the comments.

Friday, June 8, 2018

Storing user profile pictures


If you have a platform where users can have profiles -like a social network-, you're most likely finding yourself wanting to store their profile pictures somewhere. let's iterate through some of options you have to do this.

First option

Store them as binary blobs in your database. Don't do it! noone wants bulky binary blobs in their databases, they perform poorly and don't scale well.


Second option

Use a storage service like S3 and make a directory with the ID of the user, so the path will always be something like /profilepictures/{userId} and it would be really easy to reference it in the client side. until you need to use a CDN, it won't know when to revoke the cached version because it's always the same name so the cached version will always be returned until its TTL expires (unless of course you purge it).


Third option

To be able to use the power of CDNs and also keep them updated (by updating them when a user changes their profile picture and leave them cached otherwise), what you can do is, when a user changes their profile picture

  • generate a unique timestamped name for the picture by generating a UUID or something similar (which might be just a unix timestamp) and appending it to the user ID as a string before saving the file so you have something like {userID}-70bb1914-e0bf-4c10-8a85-92157acdbf42.
  • then save that generated name (or the full path if you will) in the database.
  • upload the file like normal to the blob storage service (S3) at /profilepictures/{generatedName}. You can also delete the old picture to save up some cloud space.

This will help CDNs as well as browsers cache the files as long as they don't change.


This is it. This is the problem I have faced and how I've solved it. As always their are indeed other and better ways to do it, and as always feel free to discuss them in the comments.