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.

Saturday, March 24, 2018

Azure function apps: creating a shared .csx file that uses an external library


In this post we are going to discuss how to make multiple C# Azure functions use a shared .csx that uses an external library.

The problem

Imagine the situation is like this, you have two functions in your function app that each take a blob as an input and output a bunch images with different sizes. These functions would have different inputs and outputs, say that take their input from different queues and output the images in some blob storage path.

The resizing library of choice is ImageResizer, which is available on NuGet. To install it, we add a project.json file in the root of our function with content like this.

{
  "frameworks": {
    "net46": {
      "dependencies": {
        "ImageResizer": "4.0.5"
      }
    }
  }
}

This automatically installs and adds a reference to ImageResizer to our function so we can start resizing the images.

So these two functions are essentially the same, they take an input image and output a bunch of resized images, so it's sane that we extract the common piece of code (the resizing part) into its own module.

The catch here is that the common code have to use the ImageResizer library, and the only way to install and manage it automatically is to use the project.json file.

The Solution

Some initial steps are required to make this work, so here are the prerequisites.

First thing is to add the shared file to your function app so that both of your functions can reference it.

  • go to https://portal.azure.com/ and login to your account.
  • Open Function Apps, choose your function app then click the Platform Features tab from the top navigation bar.
  • From the DEVELOPMENT TOOLS section choose Advanced tools (Kudu).
  • From the top menu, Debug console -> CMD.
  • navigate from the file explorer, choose site -> wwwroot. This is where all your functions live.

Now in the console

> mkdir shared
> cd shared
> touch resize.csx

This creates a file called resize.csx inside the shared folder and that's the file we will be using for our image resizing logic.

Now, the solutions.

One possible solution would be to downlad the .dll file for the library and upload it to the shared folder then import it inside the resize.csx file. You wouldn't then need the project.json file. This would work but you will be losing the advantage of package management that NuGet gives you, so I can't recommend this approach.

A better solution is to take advantage of the fact that the loaded .csx files are much like importing header files in the C language, in which they become part of your file and get access to all available namespaces.

We will start from the docs, which mentions that you import a shared library with the #load directive.

So in the run.csx file of one of the functions, import the shared file. Assuming that it has a function called resize that takes an image as a Stream and an array of sizes to output, it would look like this.

#load "../shared/resize.csx"

public static void Run(Stream someImage) {
    resize(someImage, sizesArray);
}

So this way the shared resize function is available in our function app and the ImageResizer is available to the resize function, due to the fact that they share the same context.

Then for any other functions that need to use the resize function, add the project.json file with the ImageResizer package and you're good to go.


That's it. These are the simplest solutions to deal with that situation. Sure there are other solutions out there, so if you have some solution that you would recommend please share it with us.

Monday, January 29, 2018

React: Parent-child lifecycle methods and refs



Introduction

This post is going to cover the order in which lifecycle methods get called in parent components and their children and where the ref callback fits in this flow, with a little story about passing a ref from a child to a sibling of that child which we are going to solve out gradually.

Backstory

Here's a little context for what got me to write this post, if you are more interested in the meat and potatoes of the thing, you might skip this section, altough things should be much clearer if you read it.

I'll clarify why things behave like this at the end of the post.

Me at work, the design has put us in a situation where a button has to focus a text input that's inside a container that's a sibling of the button's container component. I know that's confusing, so here is an image to illustrate it.

As y'all know in React, focus == ref.

So the parent had to reach into the CatList's text input to get a ref then pass it to the buttonBar.

Approach 1


We can go get the starting point straight out of the official docs

class Parent extends React.Component {
  render() {
    return (
      <div>
        <ButtonBar/>
        <CatList getRef={input => this.catInput = input}/>
      </div>
    );
  }
}

class CatList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      cats: [
        "Cat1"
      ]
    };
  }

  render() {
    return (
      <div>
        <ul>
          {
            this.state.cats.map((cat, i) => 
              <li key={i}>
                <p>{cat}</p>
              </li>
            )
          }
        </ul>
        <input type="text" ref={this.props.getRef} />
        <button> Send </button>
      </div>
    );
  }
}

class ButtonBar extends React.Component {
  render() {
    return (
      <button> Focus </button>
    );
  }
}

So We've sent the getRef function to the CatList component which is going to extract the DOM ref from the input and pass it up to the catInput property of the Parent.

So far so good. If we want to set focus to the input when the parent mounts it's as easy as

// In the Parent component
componentDidMount() {
  this.catInput.focus();
}

That works, the input is focused whenever the parent is mounted.

So we can pass the property down to the ButtonBar like that, right?

class Parent extends React.Component {
  render() {
    return (
      <div>
        <ButtonBar inputRef={this.catInput}/>
        <CatList getRef={input => this.catInput = input}/>
      </div>
    );
  }
}

class ButtonBar extends React.Component {
  constructor(props) {
    super(props);
    this.focusInput = this.focusInput.bind(this);
  }

  focusInput(e) {
    this.props.inputRef.focus();
  }

  render() {
    return (
      <button onClick={this.focusInput}> Focus </button>
    );
  }
}

Wrong, that would give an error that your props.inputRef is undefined.

Approach 2


Use the parent component's state to store the ref and pass it down to the other sibling.

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      catInput: null
    };
  }

  componentDidMount() {
    this.setState({
      catInput: this.catInput
    });
    this.catInput.focus();
  }

  render() {
    return (
      <div>
        <ButtonBar inputRef={this.state.catInput}/>
        <CatList getRef={input => this.catInput = input}/>
      </div>
    );
  }
}

class CatList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      cats: [
        "Cat1"
      ]
    };
  }

  render() {
    return (
      <div>
        <ul>
          {
            this.state.cats.map((cat, i) => 
              <li key={i}>
                <p>{cat}</p>
              </li>
            )
          }
        </ul>
        <input type="text" ref={this.props.getRef} />
        <button> Send </button>
      </div>
    );
  }
}

class ButtonBar extends React.Component {
  constructor(props) {
    super(props);
    this.focusInput = this.focusInput.bind(this);
  }

  focusInput(e) {
    this.props.inputRef.focus();
  }

  render() {
    return (
      <button onClick={this.focusInput}> Focus </button>
    );
  }
}

This works, but not for the reason you might think it works for. In fact if we set any state on the parent component, and pass the this.catInput property of the Parent (like we did in approach 1) it will work.

The thing is, setState causes a re-render, so the props are sent correctly (next section explains why the props went right this time).

That means we can replace the code inside componentDidMount of the Parent component with a forceUpdate and it will work.

// Parent component
componentDidMount() {
  this.forceUpdate();
  this.catInput.focus();
}

And in the render method we pass in the class property this.catInput to the ButtonBar.

// Parent component
render() {
  return (
    <div>
      <ButtonBar inputRef={this.catInput}/>
      <CatList getRef={input => this.catInput = input}/>
    </div>
  );
}

Meat and potatoes

To understand the reasons behind what worked and what didn't work in the previous story we can first start with how lifecycle methods are called. The order is as follows:

  • The render method of the parent (passing the props).
  • The render method of the children.
  • Ref callbacks in children.
  • The componentDidMount method of the children.
  • The componentDidMount method of the parent.

So to wrap up

  • the props are already sent before any of the hierarchy's componentDidMount methods are called.
  • The ref is not available until just before the componentDidMount of the children is called.
  • componentDidMount of the Parent is then called after all its children had called theirs.

That's why we could read the input ref in the componentDidMount of the Parent but the input prop was undefined when passed to the other component (the ButtonBar's props.inputRef).

Causing a re-render makes the prop be sent with the right value, because re-renders always give the child components the up-to-date values of their props, and that's what forceUpdate did in the last example above.

forceUpdate might not be the best solution to this kind of situation, I'd like to know what your approach would be for that matter.


That's it! I hope you enjoyed the little story.

if you have any suggestions, want to point out mistakes or share knowledge, you can always leave a comment.