Collection.modify()

Modifies all objects in the collection

Syntax

collection.modify(changes)

Parameters

changes Object containing changes to apply on all objects in the collection. Caller can supply a Function instead of Object.
  • If an Object is supplied, each key is the path to a property to change and each value is the new value to set
  • If a Function is supplied, the given function will be called for each matched object in Collection. Function retrieves the object as first argument. Function may then modify, add or delete properties of the object. When function has returned, the framework will update the given object to database with the changes made on it.

Return Value

Promise where resolved value is the number of modified objects. If any object fails to be updated, the entire operation will fail and Promise will reject. To catch the error, call Promise.catch() on the returned Promise, else the error will bubble to the aborted transaction and if not catched there, finally bubble to db.on(“error”).

Remarks

Applies given changes to all objects in the collection.

If given changes is an Object, each key in the object represents a keyPath and each value the new value to set. A key path can be the name of a property or if containing periods (.) act as a path to a property in a nested object.

If the value is a function, the function will be called for each object so that the function may modify or delete any properties on the object. A function may also replace the object with another object by using this.value = otherObject. Finally, the function may also delete the object by doing delete this.value; See samples below.

Error Handling

If any object fails to be modified or an exception occur in a callback function, entire operation will fail and transaction will be aborted.

If you catch the returned Promise, transaction will not abort, and you recieve a Dexie.ModifyError error object containing the following properties:

failuresArray of Error objects of all errors that have occurred
failedKeysArray of the keys of the failed modifications. This array will have the same order as failures so that failures[i] will always represent the failure of failedKeys[i]
successCountNumber of successful modifications made.

If you do NOT catch the returned Promise, and an error occur, the transaction will be aborted.

If you want to log the error but still abort the transaction, you must encapsulate the operation in a transaction() block and catch the transaction instead. It is also possible to catch the operation and call transaction.abort() in the catch() clause.

Sample

db.transaction("rw", db.friends, function () {

    // Mark bigfoots:
    db.friends.where("shoeSize").aboveOrEqual(47).modify({isBigfoot: 1});

    // Log all bigfoots.
    // Since in transaction, and prev operation is a write-operation, the below
    // operation will be stalled until above operation completes, ensuring we
    // get the result after the modification.

    db.friends.where("isBigfoot").equals(1).each(function(friend) {
        console.log(friend.name);
    });

}).catch (Dexie.ModifyError, function (e) {

    // ModifyError did occur
    console.error(e.failures.length + " items failed to modify");

}).catch (function (e) {
    console.error("Generic error: " + e);
});

Sample using Function

// Convert all shoeSize from european to american size:
db.friends.modify(function(friend) {
    friend.shoeSize *= 0.31; // (very approximate formula...., but anyway...)
});

Sample Replacing Object

The this pointer points to an object containing the property value. This is the same value as being sent as the first argument. To replace the object entirely you cannot use the value from the argument since “by ref” is not possible with javascript. Instead, use this.value = otherObj to change the reference, as sample code below shows:

// Replace friend with another friend:
db.friends.where("isKindToMe").equals("no").modify(function(value) {
    this.value = new Friend({name: "Another Friend"});
});

With arrow function (Supported since Dexie v1.3.4):

db.friends.where("isKindToMe").equals("no").modify((value, ref) => {
    ref.value = new Friend({name: "Another Friend"});
});

Sample Deleting Object

// Delete all friends that have been mean.
db.friends.where("hasBeenMeanToMe").equals("yes").modify(function(value) {
    delete this.value;
});

With arrow function (Supported since Dexie v1.3.4):

// Delete all friends that have been mean.
db.friends.where("hasBeenMeanToMe").equals("yes").modify((value, ref) => {
    delete ref.value;
});

The sample above is equivalent to:

db.friends.where("hasBeenMeanToMe").equals("yes").delete();

Sample using Nested Key

In this sample, we modify a property that is a nested key (a key in a nested object). We include the schema and an example object in this example just to clarify how nested objects are used.

var db = new Dexie("FriendsDB");
db.version(1).stores({ friends: "++id, name, props.shoeSize, props.bigfoot"});
db.on("populate", function () {
    db.friends.add({
        name: "Zlatan",
        props: {
            shoeSize: 47,
            bigfoot: "no" // Will be changed later ;)
        }
    });
});
db.open();

db.transaction("rw", db.friends, function () {

    // Mark bigfoots:
    db.friends
      .where("props.shoeSize").aboveOrEqual(47)
      .modify({"props.bigfoot": "yes"});

    // Log all bigfoots.
    // Since in transaction, and prev operation is a write-operation, the
    // below operation will be stalled until above operation completes, 
    // ensuring we get the result after the modification.

    db.friends.where("props.bigfoot").equals("yes").each(function(friend) {
        console.log("Found bigfoot: " + friend.name);
    });

}).catch (function (e) {
    console.error(e);
});

Table of Contents