Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove getWithDefault #19648

Merged
merged 4 commits into from Jul 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/@ember/-internals/metal/index.ts
Expand Up @@ -2,7 +2,7 @@ export { default as computed, autoComputed, isComputed, ComputedProperty } from
export { getCachedValueFor } from './lib/computed_cache';
export { default as alias } from './lib/alias';
export { deprecateProperty } from './lib/deprecate_property';
export { PROXY_CONTENT, _getPath, get, getWithDefault, _getProp } from './lib/property_get';
export { PROXY_CONTENT, _getPath, get, _getProp } from './lib/property_get';
export { set, _setProp, trySet } from './lib/property_set';
export {
objectAt,
Expand Down
48 changes: 1 addition & 47 deletions packages/@ember/-internals/metal/lib/property_get.ts
Expand Up @@ -2,7 +2,7 @@
@module @ember/object
*/
import { HAS_NATIVE_PROXY, isEmberArray, setProxy, symbol } from '@ember/-internals/utils';
import { assert, deprecate } from '@ember/debug';
import { assert } from '@ember/debug';
import { DEBUG } from '@glimmer/env';
import {
consumeTag,
Expand Down Expand Up @@ -158,52 +158,6 @@ export function _getPath<T extends object>(root: T, path: string | string[]): an
return obj;
}

/**
Retrieves the value of a property from an Object, or a default value in the
case that the property returns `undefined`.

```javascript
import { getWithDefault } from '@ember/object';
getWithDefault(person, 'lastName', 'Doe');
```

@method getWithDefault
@for @ember/object
@static
@param {Object} obj The object to retrieve from.
@param {String} keyName The name of the property to retrieve
@param {Object} defaultValue The value to return if the property value is undefined
@return {Object} The property value or the defaultValue.
@public
@deprecated
*/
export function getWithDefault<T extends object, K extends Extract<keyof T, string>>(
root: T,
key: K,
defaultValue: T[K]
): T[K] {
deprecate(
'Using getWithDefault has been deprecated. Instead, consider using Ember get and explicitly checking for undefined.',
false,
{
id: 'ember-metal.get-with-default',
until: '4.0.0',
url: 'https://deprecations.emberjs.com/v3.x#toc_ember-metal-get-with-default',
for: 'ember-source',
since: {
enabled: '3.21.0',
},
}
);

let value = get(root, key);

if (value === undefined) {
return defaultValue;
}
return value;
}

export default get;

// Warm it up
Expand Down
197 changes: 1 addition & 196 deletions packages/@ember/-internals/metal/tests/accessors/get_test.js
@@ -1,10 +1,9 @@
import { ENV } from '@ember/-internals/environment';
import { Object as EmberObject } from '@ember/-internals/runtime';
import { get, set, getWithDefault, Mixin, observer, computed } from '../..';
import { get, Mixin, observer } from '../..';
import { moduleFor, AbstractTestCase } from 'internal-test-helpers';
import { run } from '@ember/runloop';
import { destroy } from '@glimmer/destroyable';
import { track } from '@glimmer/validator';

function aget(x, y) {
return x[y];
Expand Down Expand Up @@ -205,197 +204,3 @@ moduleFor(
}
}
);

moduleFor(
'getWithDefault',
class extends AbstractTestCase {
['@test should get arbitrary properties on an object'](assert) {
expectDeprecation(() => {
let obj = {
string: 'string',
number: 23,
boolTrue: true,
boolFalse: false,
nullValue: null,
};

for (let key in obj) {
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
continue;
}
assert.equal(getWithDefault(obj, key, 'fail'), obj[key], key);
}

obj = {
undef: undefined,
};

assert.equal(
getWithDefault(obj, 'undef', 'default'),
'default',
'explicit undefined retrieves the default'
);
assert.equal(
getWithDefault(obj, 'not-present', 'default'),
'default',
'non-present key retrieves the default'
);
}, /Using getWithDefault has been deprecated. Instead, consider using Ember get and explicitly checking for undefined./);
}

['@test should call unknownProperty if defined and value is undefined'](assert) {
let obj = {
count: 0,
unknownProperty(key) {
assert.equal(key, 'foo', 'should pass key');
this.count++;
return 'FOO';
},
};

assert.equal(get(obj, 'foo'), 'FOO', 'should return value from unknown');
assert.equal(obj.count, 1, 'should have invoked');
}

['@test if unknownProperty is present, it is called using getFromEmberMetal()/set()'](assert) {
expectDeprecation(() => {
let obj = {
unknownProperty(key) {
if (key === 'foo') {
assert.equal(key, 'foo', 'should pass key');
return 'FOO';
}
},
};
assert.equal(
getWithDefault(obj, 'foo', 'fail'),
'FOO',
'should return value from unknownProperty'
);
assert.equal(
getWithDefault(obj, 'bar', 'default'),
'default',
'should convert undefined from unknownProperty into default'
);
}, /Using getWithDefault has been deprecated. Instead, consider using Ember get and explicitly checking for undefined./);
}

['@test if unknownProperty is present, it is called using accessors'](assert) {
if (ENV.USES_ACCESSORS) {
let obj = {
unknownProperty(key) {
if (key === 'foo') {
assert.equal(key, 'foo', 'should pass key');
return 'FOO';
}
},
};
assert.equal(aget(obj, 'foo', 'fail'), 'FOO', 'should return value from unknownProperty');
assert.equal(
aget(obj, 'bar', 'default'),
'default',
'should convert undefined from unknownProperty into default'
);
} else {
assert.ok('SKIPPING ACCESSORS');
}
}

['@test gives helpful deprecation when a property tracked with `get` is mutated after access within unknownProperty within an autotracking transaction']() {
class EmberObject {
foo = null;

unknownProperty() {
get(this, 'foo');
set(this, 'foo', 123);
}
}

let obj = new EmberObject();

expectDeprecation(() => {
// TODO: this must be a bug??
expectDeprecation(
/You attempted to update `undefined`, but it had already been used previously in the same computation/
);

track(() => {
get(obj, 'bar');
});
}, /You attempted to update `foo` on `EmberObject`, but it had already been used previously in the same computation/);
}

// ..........................................................
// BUGS
//

['@test (regression) watched properties on unmodified inherited objects should still return their original value'](
assert
) {
expectDeprecation(() => {
let MyMixin = Mixin.create({
someProperty: 'foo',
propertyDidChange: observer('someProperty', () => {
/* nothing to do */
}),
});

let baseObject = MyMixin.apply({});
let theRealObject = Object.create(baseObject);

assert.equal(
getWithDefault(theRealObject, 'someProperty', 'fail'),
'foo',
'should return the set value, not false'
);

run(() => destroy(baseObject));
}, /Using getWithDefault has been deprecated. Instead, consider using Ember get and explicitly checking for undefined./);
}

['@test should respect prototypical inheritance when subclasses override CPs'](assert) {
let ParentClass = EmberObject.extend({
prop: computed({
get() {
assert.ok(false, 'incorrect getter called');
return 123;
},
}),
});

let SubClass = ParentClass.extend({
get prop() {
assert.ok(true, 'correct getter called');
return 456;
},
});

let instance = SubClass.create();

instance.prop;
}

['@test should respect prototypical inheritance when subclasses override CPs with native classes'](
assert
) {
class ParentClass extends EmberObject {
@computed
get prop() {
assert.ok(false, 'incorrect getter called');
return 123;
}
}

class SubClass extends ParentClass {
get prop() {
assert.ok(true, 'correct getter called');
return 456;
}
}

let instance = SubClass.create();

instance.prop;
}
}
);
29 changes: 1 addition & 28 deletions packages/@ember/-internals/metal/tests/tracked/get_test.js
@@ -1,5 +1,5 @@
import { AbstractTestCase, moduleFor } from 'internal-test-helpers';
import { get, getWithDefault, tracked } from '../..';
import { get, tracked } from '../..';

let createObj = function () {
class Obj {
Expand Down Expand Up @@ -42,32 +42,5 @@ moduleFor(

this.assert.equal(get(obj, 'path.key.value'), 'value for some-key');
}

['@test should get arbitrary properties on an object (getWithDefault DEPRECATED)']() {
expectDeprecation(() => {
let obj = createObj();

for (let key in obj) {
this.assert.equal(getWithDefault(obj, key, 'fail'), obj[key], key);
}

class Obj {
@tracked undef = undefined;
}

let obj2 = new Obj();

this.assert.equal(
getWithDefault(obj2, 'undef', 'default'),
'default',
'explicit undefined retrieves the default'
);
this.assert.equal(
getWithDefault(obj2, 'not-present', 'default'),
'default',
'non-present key retrieves the default'
);
}, /Using getWithDefault has been deprecated. Instead, consider using Ember get and explicitly checking for undefined./);
}
}
);
1 change: 0 additions & 1 deletion packages/@ember/-internals/runtime/index.d.ts
Expand Up @@ -49,7 +49,6 @@ export class Object extends CoreObject implements Observable {
method: ObserverMethod<Target, this>
): this;
removeObserver(key: keyof this, method: ObserverMethod<this, this>): this;
getWithDefault<K extends keyof this>(key: K, defaultValue: any): unknown;
incrementProperty(keyName: keyof this, increment?: number): number;
decrementProperty(keyName: keyof this, decrement?: number): number;
toggleProperty(keyName: keyof this): boolean;
Expand Down
20 changes: 0 additions & 20 deletions packages/@ember/-internals/runtime/lib/mixins/observable.js
Expand Up @@ -5,7 +5,6 @@
import { peekMeta } from '@ember/-internals/meta';
import {
get,
getWithDefault,
set,
getProperties,
setProperties,
Expand Down Expand Up @@ -404,25 +403,6 @@ export default Mixin.create({
return hasListeners(this, `${key}:change`);
},

/**
Retrieves the value of a property, or a default value in the case that the
property returns `undefined`.

```javascript
person.getWithDefault('lastName', 'Doe');
```

@method getWithDefault
@param {String} keyName The name of the property to retrieve
@param {Object} defaultValue The value to return if the property value is undefined
@return {Object} The property value or the defaultValue.
@public
@deprecated
*/
getWithDefault(keyName, defaultValue) {
return getWithDefault(this, keyName, defaultValue);
},

/**
Set the value of a property to the current value plus some amount.

Expand Down