DoneJS StealJS jQuery++ FuncUnit DocumentJS
3.14.1
5.0.0 4.3.0 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-compute
      • can-define
      • can-define/list/list
      • can-define/map/map
      • can-define-stream
      • can-define-stream-kefir
      • can-event
      • can-event/async/async
      • can-event/batch/batch
      • can-event/lifecycle/lifecycle
      • can-kefir
      • can-list
      • can-map
      • can-map-backup
      • can-map-define
      • can-observation
      • can-observe
      • can-simple-map
      • can-simple-observable
      • can-stream
      • can-stream-kefir
    • Data Modeling
      • can-connect
        • behaviors
          • ./base/
          • ./cache-requests/
          • ./can/constructor-hydrate/
          • ./can/map/
          • ./can/merge/
          • ./can/ref/
            • methods
              • init
            • hydrators
              • Map.Ref
          • ./constructor/callbacks-once/
          • ./constructor/
          • ./constructor/store/
          • ./data/callbacks/
          • ./data/callbacks-cache/
          • ./data/combine-requests/
          • ./data/localstorage-cache/
          • ./data/memory-cache/
          • ./data/parse/
          • ./data/url/
          • ./data/worker/
          • ./fall-through-cache/
          • ./real-time/
        • modules
          • ./can/base-map/
          • ./can/model/
          • ./can/super-map/
          • ./can/tag/
          • ./helpers/map-deep-merge
          • ./helpers/weak-reference-map
        • data types
          • DataInterface
          • Instance
          • InstanceInterface
          • List
          • ListData
      • can-connect-cloneable
      • can-connect-feathers
      • can-connect-ndjson
      • can-connect-signalr
      • can-fixture
      • can-fixture-socket
      • can-ndjson-stream
      • can-set
    • Views
      • can-component
      • can-ejs
      • can-element
      • can-react-component
      • can-stache
      • can-stache/helpers/route
      • can-stache-bindings
      • can-stache-converters
      • can-view-autorender
      • can-view-callbacks
      • can-view-href
      • 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-pushstate
    • JS Utilities
      • can-assign
      • can-define-lazy-value
      • can-globals
      • can-key-tree
      • can-make-map
      • can-parse-uri
      • can-string
      • can-string-to-any
      • can-util
      • can-zone
      • can-zone-storage
    • DOM Utilities
      • can-ajax
      • can-attribute-encoder
      • can-control
      • can-dom-events
      • can-event-dom-enter
      • can-event-dom-radiochange
      • can-jquery
    • 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-namespace
      • can-reflect
      • 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

can/ref

  • Edit on GitHub

Handle references to instances in the data returned by the server. Allows several means of loading referenced instances, determined on-the-fly.

canRef( baseConnection )

Adds a reference type to connection.Map that loads the related type or holds onto an existing one. This handles circular references and loads relevant data as needed. The reference type can be loaded by:

  • it's data being included in the response for the referencing instance
  • having an existing instance available in the instanceStore
  • lazy loading via the connection for the reference type

Parameters

  1. baseConnection {Object}:

    can-connect connection object that is having the can/ref behavior added on to it. Expects the can/map behavior to already be added to this base connection. If the connect helper is used to build the connection, the behaviors will automatically be ordered as required.

Returns

{Object}:

a connection with the Map having the reference type property (Map.Ref.type) created by can/ref.

Use

can/ref is useful when the server might return either a reference to a value or the value itself. For example, in a MongoDB setup, a request like GET /game/5 might return:

{
  id: 5,
  teamRef: 7,
  score: 21
}

But a request like GET /game/5?$populate=teamRef might return:

{
  id: 5,
  teamRef: {id: 7, name: "Cubs"},
  score: 21
}

can/ref can handle this ambiguity and even make lazy loading possible.

To use can/ref, first create a Map and a connection for the referenced type:

var Team = DefineMap.extend({
  id: 'string'
});

connect([
  require("can-connect/constructor/constructor"),
  require("can-connect/constructor/store/store"),
  require("can-connect/can/map/map"),
  require("can-connect/can/ref/ref")
],{
    Map: Team,
    List: Team.List,
    ...
})

The connection is necessary because it creates an instance store which will hold instances of Team that the Team.Ref type will be able to access.

Now we can create a reference to the Team within a Game map and the Game's connection:

var Game = DefineMap.extend({
  id: 'string',
  teamRef: {type: Team.Ref.type},
  score: "number"
});

superMap({
  Map: Game,
  List: Game.List
})

Now, teamRef is a Map.Ref type, which will house the id of the reference no matter how the server returns data, e.g. game.teamRef.id.

For example, without populating the team data:

Game.get({id: 5}).then(function(game){
  game.teamRef.id //-> 7
});

With populating the team data:

Game.get({id: 5, $populate: "teamRef"}).then(function(game){
  game.teamRef.id //-> 7
});

The values of other properties and methods on the Map.Ref type are determined by if the reference was populated or the referenced item already exists in the instanceStore.

For example, value, which points to the referenced instance, will be populated if the reference was populated:

Game.get({id: 5, $populate: "teamRef"}).then(function(game){
  game.teamRef.value.name //-> 5
});

Or, it will be populated if that instance had been loaded through another means and it’s in the instance store:

Team.get({id: 7}).then(function(team){
  // binding adds things to the store
  team.on("name", function(){})
}).then(function(){
  Game.get({id: 5}).then(function(game){
    game.teamRef.value.name //-> 5
  });
})

value is an asynchronous getter, which means that even if the referenced value isn't populated or loaded through the store, it can be lazy loaded. This is generally most useful in a template.

The following will make an initial request for game 5, but when the template tried to read and listen to game.teamRef.value.name, a request for team 7 will be made.

var template = stache("{{game.teamRef.value.name}} scored {{game.score}} points");
Game.get({id: 5}).then(function(game){
  template({game: game});
});

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

On this page

Get help

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