[Solved] Question: "get" v.s. "default"


#1

Sometimes I see:

const AppViewModel = DefineMap.extend('App', {
  get title() {
    return 'My Cool App';
  },
});

And other times I see:

const AppViewModel = DefineMap.extend('App', {
  title: {
    default: 'My Cool App';
  },
});

What’s the difference? I don’t understand the inconsistency outside of perhaps personal preference.

EDIT:

I’ve noticed I’ll get this error in dev when returning an object from a get function:

So I’m guessing you only return strings from a get function? Not really sure where to look in the documentation to get clarification on this. Skimmed through can-define but nothing popped out.


#2

Did you happen to see:

https://canjs.com/doc/can-define.types.get.html

and

https://canjs.com/doc/can-define.types.default.html

while skimming can-define? I’d like to make sure folks can find these. You can see them here in the sidebar:

image

default is probably easier to understand. It creates a default value. This can happen very fast. It also can only happen once per instance. Both of those examples should probably be using default. I see get used a lot of places where default is probably better. Despite this get probably isn’t harmful.

get is a computed getter property. I’d read through the docs to get a better understanding. If you have other questions after reading, let me know.

I’ve noticed I’ll get this error in dev when returning an object from a get function:

What you return has nothing to do with that error. That error happens because a get property is being set and the getter has no way of accessing the value that was set.

Think of it like lighting a match within the event horizon of a black hole. It’s pointless.

For example:

var Type = DefineMap.extend({
  get foo(){
    return 32; // return object, string, anything, doesn't matter
  }
})

var instance = new Type();
instance.foo = {} // set an object, string, anything, doesn't matter

foo is ALWAYS going to return 32 so setting it to anything else is “pointless” and we give that warning.


#3

I guess one problem is the syntax on the docs never covers the usage like:

  get title() {
    return 'My Cool App';
  },

As far as I could tell, using get like this wasn’t mentioned on any of the pages you linked.

Maybe this is an ES6 feature (or something?) that essentially translates to:

  title: {
    get: function() { return 'My Cool App'; }
  },

Although, I’m just making an assumption because I don’t see this usage mentioned anywhere in the can-define documentation.

It’s also still not clear when default and get are interchangeable and I don’t see any advice on when to use either or any cross-referencing between the two documentation pages you linked.

So, in addition to explaining the different get syntaxes, I think a note or short paragraph under usage that explains the different use cases pointing default to get and get to default would be helpful for novice users that might see the same thing done in two different ways without any clear reason as to why.

EDIT:

Perhaps it would be helpful to summarize the relevant parts of this MDN article about getter:

The get syntax binds an object property to a function…

  • It must have exactly zero parameters

Something along the lines of this explanation:

EDIT:

I see this explanation in the place-my-order guide:

Something like that might be useful to include in the CanJS docs. A question I have after reading that is if you specify default, does that stop external values from setting that property?


#4

I was trying to use get to return the value of env instead of using default like:

  env: {
    default: () => ({ NODE_ENV: 'development' }),
  },

So, the event horizon error was happening even though I wasn’t setting env anywhere.

I assume steal or can is setting env on the view model?

This is actually something I’ve been trying to figure out for a while, where does this.env come from and who is setting it? Does it get set on all view models directly or is it a global variable or does it only get set on the root app view model somehow?


#5

done-ssr sets it. Only gets set on the app view model. @matthewp would know more.


#6

I think that’s all I need to know, although I would greatly appreciate a link to the source code that does said setting of env on the app view model as I wasn’t able to find it (not really sure which repo to look in).


#7

@justinbmeyer @matthewp Currently I’m noticing this.env.NODE_ENV goes from production to undefined after reattachment, which means my app can’t correctly check the env in the running app client stache, which I believe is supposed to be possible.

EDIT:

I’ve opened an issue in done-ssr regarding the issues I’ve been having with env.NODE_ENV:

Although, I might just be misunderstanding limitations in detecting “production” on the client side?