Lazy Variables in a Stimulus Controller


#1

Is there anything available in Stimulus (or JavaScript ES6) to create “lazy” variables? For example, in Ruby we can do something like this:

def user_id
  @user_id ||= compute_user_id #resource intensive
end

The first time #user_id is called it will compute it but subsequent calls will used the “cached” version.


#2

This is usually called memoization. There are many techniques for memoizing functions in ES6, but Stimulus doesn’t (yet?) have one built-in.

https://lodash.com/docs/4.17.10#memoize
https://steelsojka.github.io/lodash-decorators/variable/index.html#static-variable-Memoize


#3

I like this slight variation of MDN’s “Smart / self-overwriting / lazy getters”:

class X {
  // …
  
  get id() {
    console.log("Computing ID!")
    const value = computeId()
    Object.defineProperty(this, "id", { value })
    return value
  }
}
> x = new X()
X {}

> x.id
Computing ID!
123

> x.id
123

> x.id
123

#4

Thanks for the context and background, @sam! I would love to see something like this built in to Stimulus. Especially since we already have the targets declaration.

And thanks for the example, @javan! I ended up going with something like this, and was wondering if there are any pitfalls I may be missing.

get search() {
  if (this._search == undefined) {
    this._search = new mapkit.Search
  }
  return this._search
}