DoneJS StealJS jQuery++ FuncUnit DocumentJS
4.3.0
5.0.0 3.13.1 2.3.35
  • About
  • Guides
  • API Docs
  • Community
  • Contributing
  • Bitovi
    • Bitovi.com
    • Blog
    • Design
    • Development
    • Training
    • Open Source
    • About
    • Contact Us
  • About
  • Guides
  • API Docs
    • Observables
      • can-bind
      • can-compute
      • can-debug
      • can-define
        • static
          • types
        • types
          • PropDefinition
          • ValueOptions
        • behaviors
          • default
          • Default
          • get
          • identity
          • serialize
          • set
          • type
          • Type
          • value
      • can-define/list/list
      • can-define/map/map
      • can-define-backup
      • can-define-stream
      • can-define-stream-kefir
      • can-event-queue
      • can-kefir
      • can-list
      • can-map
      • can-map-define
      • can-observation
      • can-observation-recorder
      • can-observe
      • can-simple-map
      • can-simple-observable
      • can-stream
      • can-stream-kefir
      • can-value
    • Data Modeling
      • can-connect
      • can-connect-feathers
      • can-fixture
      • can-fixture-socket
      • can-ndjson-stream
      • can-set
    • Views
      • can-component
      • can-stache
      • can-stache-bindings
      • can-stache-converters
      • can-stache-route-helpers
      • can-view-autorender
      • can-view-callbacks
      • can-view-import
      • can-view-live
      • can-view-model
      • can-view-nodelist
      • can-view-parser
      • can-view-scope
      • can-view-target
      • react-view-model
      • react-view-model/component
      • steal-stache
    • Routing
      • can-deparam
      • can-param
      • can-route
      • can-route-hash
      • can-route-mock
      • can-route-pushstate
    • JS Utilities
      • can-assign
      • can-define-lazy-value
      • can-diff
      • can-globals
      • can-join-uris
      • can-key
      • can-key-tree
      • can-make-map
      • can-parse-uri
      • can-queues
      • can-string
      • can-string-to-any
      • can-util
      • can-zone
      • can-zone-storage
    • DOM Utilities
      • can-ajax
      • can-attribute-encoder
      • can-child-nodes
      • can-control
      • can-dom-data
      • can-dom-events
      • can-dom-mutate
      • can-event-dom-enter
      • can-event-dom-radiochange
      • can-fragment
    • Data Validation
      • can-define-validate-validatejs
      • can-validate
      • can-validate-interface
      • can-validate-legacy
      • can-validate-validatejs
    • Typed Data
      • can-cid
      • can-construct
      • can-construct-super
      • can-data-types
      • can-namespace
      • can-reflect
      • can-reflect-dependencies
      • can-reflect-promise
      • can-types
    • Polyfills
      • can-symbol
      • can-vdom
    • Core
    • Infrastructure
      • can-global
      • can-test-helpers
    • Ecosystem
    • Legacy
  • Community
  • Contributing
  • GitHub
  • Twitter
  • Chat
  • Forum
  • News
Bitovi

get

  • Edit on GitHub

Specify what happens when a certain property is read on a map. get functions work like a can-compute and automatically update themselves when a dependent observable value is changed.

get( [lastSetValue] )

Defines the behavior when a property value is read on a instance. Used to provide properties that derive their value from other properties on the object, or the property value that was set on the object.

Specify get like:

{
    propertyName: {
        get: function() { /* ... */ }
    },
    propertyName: {
        get: function( lastSetValue ) { /* ... */ }
    }
}

Parameters

  1. lastSetValue {*}:

    The value last set by instance.propertyName = value. Typically, lastSetValue should be an observable value, like a can-compute or promise. If it's not, it's likely that a set should be used instead.

Returns

{*}:

The value of the property.

get( lastSetValue, resolve(value) )

Asynchronously defines the behavior when a value is read on an instance. Used to provide property values that are available asynchronously.

Only observed properties (via on, addEventListener, etc) will be passed the resolve function. It will be undefined if the value is not observed. This is for memory safety.

Specify get like:

{
    propertyName: {
        get: function( lastSetValue, resolve ) { /* ... */ }
    }
}

Parameters

  1. lastSetValue {*}:

    The value last set by instance.propertyName = value.

  2. resolve {function(value)|undefined}:

    Updates the value of the property. This can be called multiple times if needed. Will be undefined if the value is not observed.

Returns

{*}:

The value of the property before resolve is called. Or a value for unobserved property reads to return.

Use

Getter methods are useful for:

  • Defining virtual properties on a map.
  • Defining property values that change with their internal set value.

Virtual properties

Virtual properties are properties that don't actually store any value, but derive their value from some other properties on the map.

Whenever a getter is provided, it is wrapped in a can-compute, which ensures that whenever its dependent properties change, a change event will fire for this property also.

const Person = DefineMap.extend( {
    first: "string",
    last: "string",
    fullName: {
        get: function() {
            return this.first + " " + this.last;
        }
    }
} );

const p = new Person( { first: "Justin", last: "Meyer" } );

p.fullName; // "Justin Meyer"

p.on( "fullName", function( ev, newVal ) {
    newVal; //-> "Lincoln Meyer";
} );

p.first = "Lincoln";

Asynchronous virtual properties

Often, a virtual property's value only becomes available after some period of time. For example, given a personId, one might want to retrieve a related person:

const AppState = DefineMap.extend( {
    personId: "number",
    person: {
        get: function( lastSetValue, resolve ) {
            Person.get( { id: this.personId } )
                .then( function( person ) {
                    resolve( person );
                } );
        }
    }
} );

Asynchronous properties should be bound to before reading their value. If they are not bound to, the get function will be called each time.

The following example will make multiple Person.get requests:

const state = new AppState( { personId: 5 } );
state.person; //-> undefined

// called sometime later /* ... */
state.person; //-> undefined

However, by binding, the compute only reruns the get function once personId changes:

const state = new AppState( { personId: 5 } );

state.on( "person", function() {} );

state.person; //-> undefined

// called sometime later
state.person; //-> Person<{id: 5}>

A template like can-stache will automatically bind for you, so you can pass state to the template like the following without binding:

const template = stache( "<span>{{person.fullName}}</span>" );
const state = new AppState( {} );
const frag = template( state );

state.personId = 5;
frag.childNodes[ 0 ].innerHTML; //=> ""

// sometime later
frag.childNodes[ 0 ].innerHTML; //=> "Lincoln Meyer"

The magic tags are updated as personId, person, and fullName change.

Properties values that change with their internal set value

A getter can be used to derive a value from a set value. A getter's lastSetValue argument is the last value set by instance.propertyName = value.

For example, a property might be set to a compute, but when read, provides the value of the compute.

const MyMap = DefineMap.extend( {
    value: {
        get: function( lastSetValue ) {
            return lastSetValue();
        }
    }
} );

const map = new MyMap();
const compute = compute( 1 );
map.value = compute;

map.value; //-> 1
compute( 2 );
map.value; //-> 2

This technique should only be used when the lastSetValue is some form of observable, that when it changes, can update the getter value.

For simple conversions, set or type should be used.

Updating the virtual property value

It's common to update virtual property values instead of replacing it.

The following example creates an empty locationIds can-define/list/list when a new instance of Store is created. However, as locations change, the can-define/list/list will be updated with the ids of the locations.

const Store = DefineMap.extend( {
    locations: DefineList,
    locationIds: {
        Default: DefineList,
        get: function( initialValue ) {
            const ids = this.locations.map( function( location ) {
                ids.push( location.id );
            } );
            return initialValue.replace( ids );
        }
    }
} );

CanJS is part of DoneJS. Created and maintained by the core DoneJS team and Bitovi. Currently 4.3.0.

On this page

Get help

  • Chat with us
  • File an issue
  • Ask questions
  • Read latest news