Skip to content

incrementalPatch does not work as expected for documents with nested fields. #7430

@alex-zywicki

Description

@alex-zywicki

Given a document structure like

{
    "foo": "bar",
    "data": {
        "field1":  1,
        "field2": 2,
    }
}

a call to incrementalPatch like

doc.incrementalPatch({
    data: {
        field1: 3
    }
})

will result in a new object state like

{
    "foo": "bar",
    "data": {
        "field1":  3,
        // "field2": 2, This field was removed
    }
}

After looking at the implementation https://github.com/pubkey/rxdb/blob/master/src/rx-document.ts#L316

It appears that incrementalPatch simply does a "one level" shallow patch instead of a "deep merge" operation so the output would be

{
    "foo": "bar",
    "data": {
        "field1":  3, // The field was changed, but other fields not interfered with
        "field2": 2,
    }
}

A simple potential solution would be to leverage a package like https://www.npmjs.com/package/object-deep-merge (I cannot personally vouch for this library, it was what I found when searching) or to implement that functionality manually in RxDB.

That would mean updating the current implementation from

    incrementalPatch<RxDocumentType = any>(
        this: RxDocument<RxDocumentType>,
        patch: Partial<RxDocumentType>
    ): Promise<RxDocument<RxDocumentType>> {
        return this.incrementalModify((docData) => {
            Object
                .entries(patch)
                .forEach(([k, v]) => {
                    (docData as any)[k] = v;
                });
            return docData;
        });
    },

to something like

    incrementalPatch<RxDocumentType = any>(
        this: RxDocument<RxDocumentType>,
        patch: Partial<RxDocumentType>
    ): Promise<RxDocument<RxDocumentType>> {
        return this.incrementalModify((docData) => {
            return merge(docData, patch);
        });
    },

I would be happy to provide further context to help prove the existence of the problem, and write a PR with the proposed change if this seems acceptable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions