Null free safer JavaScript inspired by Rust Option type.

Hi everyone, My first story here, hopefully you all will enjoy this.

I used to write JavaScript and I believe as everyone I forgot to check whether a result is null now and then and horribly failed when I present the app to my client.

Lets see the following situation:

let foo = document.querySelector(".foo")

Here we get a the first HTML element with the class foo , But what happens if there's no such element. Well the solution is quite simple, do this

if (foo)
//do something with foo

So this is a solution, yes, but, is it the best solution despite this being the best practice. I believe not.

Past couple months, I was playing with Rustlang -a very painfull to learn language with really good points- they solved this problem using something called an Option type.

Basically, an option can be either something or nothing and you cannot by accident use nothing as something it simply won’t compile.

So what if we had an Option type in JavaScript and if we knew that querySelector() returns an option how the code would look.

let foo = document.querySelector(".foo")
foo.Some(elem=>{/*do something here with 100% safe elem*/})//not to be confused with Array.prototype.some

I believe this way of writing code would be a lot nicer and easier for us and it can be somewhat achieved using the Promises.

So lets write a secure wrapper for the querySelector.I am going to use a bit of TypeScript syntax here to annotate the types so it is easier to understand whats going on.

function SecureQuerySelector(s:String):Promise<HTMLElement>
{
const el = document.querySelector(s)
return el?Promise.resolve(<HTMLElement>el):Promise.reject(null)
}

And now lets see how we would use this.

let foo = SecureQuerySelector(".foo")
foo.then(e=>{/*e is safe to use and for sure is an element*/})
.catch(err=>{/*catch error if necessary */})

This was just an example how to wrap things using Promises.

As a conclusion, using promises we can write wrappers or libraries that is guaranteed not to fail at run-time and make the life easier for ourselves and other developers. Rust made me think about a lot of well accepted best practices. If something was thought to be a best practice ages ago it really doesn't have to apply today’s scenarios.