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
      • 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
        • ./deep/
        • ./list/
        • ./map/
        • ./merge-deep/
        • ./patcher/
      • 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

can-diff/deep/deep

  • Edit on GitHub

Take a difference of nested maps or lists.

diffDeep(destination, source)

Find the differences between two objects or lists, including nested maps or lists.

import {diff} from "can";

diff.deep({inner: {}}, {inner: {a:'foo'}})
//-> [{
//    key: 'inner.a',
//    type: 'add',
//    value: 'foo'
// }]


patches = diff.deep({inner: []}, {inner: ['a']});
//-> [{
//    key: 'inner',
//    type: "splice",
//    index: 0,
//    deleteCount: 0,
//    insert: ['a']
// }]

Parameters

  1. destination {Object}:

    The object that will be updated.

  2. source {Object}:

    The object used to update destination.

Returns

{Array<Patches>}:

An array of patches objects. All patch objects will have a key property, even "splice" type patch objects. The key is the property that was changed. A dot (.) in the key signifies that the key was part of a nested property.

Use

mergeDeep is useful when dealing with nested data sources. It will make sure that the right nested objects get updated.

For example, say a Todo and its nested User type are defined as follows:

const User = DefineMap.extend("User",{
    id: "number",
    name: "string"
});

const Todo = DefineMap.extend("Todo",{
    id: {identity: true},
    name: "string",
    complete: "boolean",
    assignedTo: [User]
});

If a todo like the following:

var justin = new User({id: 20, name: "Justin"}),
    ramiya = new User({id: 21, name: "Ramiya"});

var todo = new Todo({
    id: 1,
    name: "mow lawn",
    complete: false,
    assignedTo: [justin, ramiya]
});

is updated with data like:

import {diff} from "diff";
diff.mergeDeep(todo, {
    id: 1,
    name: "mow lawn",
    complete: true,
    assignedTo: [{
        id: 21, name: "Ramiya Meyer"
    }]
})

NOTICE: The todo.assignedTo array removes the Justin todo and updates the Ramiya todo.

Without specifying the identity property of User, the justin instance's id and name will be updated (this is what updateDeep would do):

justin.id //-> 21
justin.name //-> "Ramiya Meyer"

However, if the User object's identity property is specified as follows:

const User = DefineMap.extend("User",{
    id: {identity: true, type: "number"},
    name: "string"
});

When the update happens, the ramiya instance will be updated correctly:

ramiya.id //-> 21
ramiya.name //-> "Ramiya Meyer"

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