Skip to content

AccessMember.evaluate should always return undefined for non-existing members #795

@nenadvicentic

Description

@nenadvicentic

The Issue

Current version of [email protected] resolves value of non-existing member of an object differently when the object is null vs undefined or non existant.

For example, binding expression foo.bar would resolve to null for:

{ foo: null }

but would resolve to undefined for:

{ foo: undefined }

and

{}

while if foo is an empty object, binding expression foo.bar would correctly return undefined:

{ foo: {} }

This unpredictability produces issue in some binding scenarios. For example:

<input type="radio" model.bind="null" checked.bind="foo.bar" />
<input type="radio" model.bind="false" checked.bind="foo.bar" />
<input type="radio" model.bind="true" checked.bind="foo.bar" />

The culprit is this method:

binding/src/ast.js

Lines 251 to 254 in ed35588

evaluate(scope, lookupFunctions) {
let instance = this.object.evaluate(scope, lookupFunctions);
return instance === null || instance === undefined ? instance : instance[this.name];
}

Instead of returning instance, it should return undefined:

evaluate(scope, lookupFunctions) {
    let instance = this.object.evaluate(scope, lookupFunctions);
    return instance === null || instance === undefined ? undefined: instance[this.name];
  }

Expected behavior

foo.bar binding expression should return undefined for all 4 cases:

{ foo: null }
{ foo: undefined }
{ foo: {} }
{}

It would also be consistant with result of JavaScript optinal chaning syntax this.foo?.bar.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions