A collection of Ember computed macros. All the macros are composable, meaning you can nest them to your heart's content, like so:
result: conditional(and(not('value1'), 'value2'), sum('value3', 1), collect('value4', toUpper('value5'))) // lisp much?Arguments to macros can be:
- A string, in which case it references the name of a property whose value is used for the calculation
- A non-string value, in which case it is used as such
- A raw macro, which lets you use a string as the value without referencing a property
- Another macro
Examples of these different usages:
source1: 'my value',
source2: 2
value1: equal('source1', 'source2'), // false
value2: equal('source2', 2), // true
value3: equal('source1', raw('my value')) // true
value4: equal('source2', sum(1, 1)) // trueThree essential primitive macros are re-exported from a different addon: ember-macro-helpers
- computed makes composing macros easier
- raw allows you to escape string literals to be used in macros
- writable makes setting macros possible
import computed from 'ember-awesome-macros/computed';
import raw from 'ember-awesome-macros/raw';
import writable from 'ember-awesome-macros/writable';
// or
import { computed, raw, writable } from 'ember-awesome-macros';If you have any opinions or want a new macro added, just ask! Or feel free to submit a pull request.
- Ember.js v3.8 or above
- Ember CLI v2.13 or above
- Node.js v8 or above
ember install ember-awesome-macros
import nameOfMacro from 'ember-awesome-macros/name-of-macro';
// or
import { nameOfMacro } from 'ember-awesome-macros';array.anycollectarray.compactarray.concatarray.everyarray.filterByarray.filterarray.findByarray.findarray.firstarray.groupByarray.includesarray.indexOfarray.invokearray.isAnyarray.isEveryarray.joinarray.lastIndexOfarray.lastarray.lengtharray.mapByarray.maparray.objectAtarray.reducearray.reversearray.rejectByarray.slicearray.sortByarray.sortarray.uniqByarray.uniqarray.without
string.camelizestring.capitalizestring.classifystring.dasherizestring.decamelizestring.escapeExpressionstring.htmlSafestring.indexOfstring.isHtmlSafestring.lastIndexOfstring.lengthstring.matchstring.replacestring.splitstring.substrstring.substringtagstring.titleizestring.toLowerstring.toUpperstring.trimstring.underscore
See [https://github.com/kellyselden/ember-macro-helpers#custom-macros].
alias for sum
same as Ember.computed.and, but allows composing
source1: false,
source2: true,
source3: false,
value1: and('source1', 'source2', 'source3'), // false
value2: and(not('source1'), 'source2', not('source3')) // truewraps Ember.Array.any, allows composing
array: Ember.A([1, 2]),
value1: array.any('array', val => val === 2), // true
value2: array.any('array', val => val === 3) // falsewraps Ember.Array.compact, allows composing
array: Ember.A([1, 2, null]),
value: array.compact('array') // [1, 2]wraps Array.prototype.concat(), allows composing
array1: Ember.A([1, 2]),
array2: Ember.A([3, 4]),
string: '3,4',
example: array.concat('array1', 'array2'), // [1, 2, 3, 4]
composingExample: array.concat('array1', split('string', raw(','))) // [1, 2, 3, 4]wraps Ember.Array.every, allows composing
array: Ember.A([1, 1]),
value1: array.every('array', val => val === 1), // true
value2: array.every('array', val => val === 2) // falsewraps Ember.Array.filterBy, allows composing
array: Ember.A([{ test: 1 }, { test: 2 }]),
key: 'test',
referenceValue: 1,
value1: array.filterBy('array', 'key', 2), // [{ test: 2 }]
value2: array.filterBy('array', raw('test'), 'referenceValue') // [{ test: 1 }]wraps Ember.Array.filter, allows composing
array: Ember.A([{ test: 1 }, { test: 2 }]),
value: array.filter('array', item => item.test === 2) // [{ test: 2 }]wraps Ember.Array.findBy, allows composing
array: Ember.A([{ test: 1 }, { test: 2 }]),
key: 'test',
referenceValue: 1,
value1: array.findBy('array', 'key', 2), // { test: 2 }
value2: array.findBy('array', raw('test'), 'referenceValue') // { test: 1 }wraps Ember.Array.find, allows composing
array: Ember.A([{ test: 1 }, { test: 2 }]),
value: array.find('array', item => item.test === 2) // { test: 2 }get the first item of an array
array: ['1', '2'],
string: '1, 2',
example: array.first('array'), // '1'
composingExample: array.first(split('string', raw(', '))) // '1'allows to group an array of objects by key with an optional comparator
array: Ember.A([{ test: 1, name: 'foo'}, { test: 2, name: 'foo' }, { test: 1, name: 'bar' }]),
key: 'test',
value: array.groupBy('array', 'key')
/*
[
{
key: 'test',
value: 1,
items: [{ test: 1 , name: 'foo' }, { test: 1 , name: 'bar' }]
},
{
key: 'test',
value: 2,
items: [{ test: 2 , name: 'foo' }]
}
]
*/The comparator is required if grouping by a key representing a complex object like Date
// Given two different objects that represent the same info
// today1 = new Date();
// today2 = new Date();
// randomDate = new Date(2017, 1, 1);
array: Ember.A([
{ test: 1 , date: today1 },
{ test: 2 , date: today2 },
{ test: 1 , date: randomDate }
]),
key: 'date'
// without comparator
value1: array.groupBy('array', 'key'),
/*
[
{
key: 'date',
value: today1,
items: [{ test: 1 , date: today1 }]
},
{
key: 'date',
value: today2,
items: [{ test: 2 , date: today2 }]
},
{
key: 'date',
value: randomDate,
items: [{ test: 1 , date: randomDate }]
}
]
*/
// with comparator
value2: array.groupBy('array', 'key', (groupValue, currentValue) => {
return groupValue.getTime() === currentValue.getTime();
})
/*
[
{
key: 'date',
value: today1,
items: [{ test: 1 , date: today1 }, { test: 2 , date: today2 }]
},
{
key: 'date',
value: randomDate,
items: [{ test: 1 , date: randomDate }]
}
]
*/implements Array.prototype.includes(), allows composing
array: Ember.A(['my value 1', 'my value 2']),
source1: 'my value 2',
source2: 'my value 3',
value1: array.includes('array', 'source1'), // true
value2: array.includes('array', 'source2'), // false
value3: array.includes(collect(raw('my value 1'), raw('my value 2')), raw('my value 1')) // truewraps Array.prototype.indexOf(), allows composing
array: [2, 5, 9, 2],
referenceValue: 9,
value1: array.indexOf('array', 2), // 0
value2: array.indexOf('array', 2, 2), // 3
value3: array.indexOf('array', 'referenceValue') // 2wraps Ember.Array.invoke(), allows composing
array: [{
foo(arg) {
return 'bar-' + arg;
}
}],
value1: array.invoke('array', 'foo', raw('baz')), // ['bar-baz']
value2: array.invoke('array', 'foo', 'arg'), // ['bar-hello']
value3: array.invoke('array', 'foo'), // ['bar-']
arg: 'hello'wraps Ember.Enumerable.isAny, allows composing
array: Ember.A([{ test: 1 }, { test: 2 }]),
key: 'test',
value1: 2,
value2: 3,
result1: array.isAny('array', 'key', 'value1'), // true
result2: array.isAny('array', 'key', 'value2') // falsewraps Ember.Enumerable.isEvery, allows composing
array1: Ember.A([{ test: 1 }, { test: 1 }]),
key: 'test',
value1: 1,
value2: 2,
result1: array.isEvery('array', 'key', 'value1'), // true
result2: array.isEvery('array', 'key', 'value2') // falsewraps Array.prototype.join(), allows composing
array: Ember.A(['1', '2']),
separator: ', ',
value1: array.join('values', 'separator'), // '1, 2'
value2: array.join(collect(raw('1'), raw('2')), raw(', ')) // '1, 2'wraps Array.prototype.lastIndexOf(), allows composing
array: [2, 5, 9, 2],
referenceValue: 9,
value1: array.lastIndexOf('array', 2), // 3
value2: array.lastIndexOf('array', 2, 2), // 0
value3: array.lastIndexOf('array', 'referenceValue') // 2get the last item of an array
array: ['1', '2'],
string: '1, 2',
example: array.last('array'), // '2'
composingExample: array.last(split('string', raw(', '))) // '2'wraps Array.prototype.length, allows composing
array: Ember.A([1, 2]),
string: '1,2',
example: array.length('array'), // 2
composingExample: array.length(split('string', raw(','))) // 2wraps Ember.Array.mapBy, allows composing
array: Ember.A([{ test: 1 }, { test: 2 }]),
key: 'test',
value: array.mapBy('array', 'key') // [1, 2]wraps Ember.Array.map, allows composing
array: Ember.A([{ test: 1 }, { test: 2 }]),
value: array.map('array', item => item.test) // [1, 2]wraps Ember.Array.objectAt, allows composing
array: Ember.A(['my value']),
source1: 0,
source2: 1,
value1: array.objectAt('array', 'source1'), // 'my value'
value2: array.objectAt('array', 'source2'), // undefined
value3: array.objectAt(collect(raw('my value 1')), raw(0)) // 'my value'wraps Array.prototype.reduce(), allows composing
Your initial value must be a factory function if you plan to mutate it in the reduce, otherwise it would continually mutate the same object every recalculation. You can still pass an object, just be careful not to mutate it.
array: ['one', 'two'],
value1: array.reduce(
'array',
(obj, cur, i) => {
obj[cur] = i;
return obj;
},
// initial value is a factory function because we mutate the object
() => ({})
), // { one: 0, two: 1 }
string: 'one, two',
value2: array.reduce(
split('string', raw(', ')),
(arr, cur, i) => arr.concat(cur, i),
//initial value is an array because it is not mutated
[]
) // ['one', 0, 'two', 1]wraps Ember.Array.rejectBy, allows composing
array: Ember.A([{ test: 1 }, { test: 2 }]),
key: 'test',
value: array.rejectBy('array', 'key', 2) // [{ test: 1 }]wraps Array.prototype.reverse() (calls slice() first as to not mutate), allows composing
array: [1, 2, 3],
value1: array.reverse('array'), // [3, 2, 1]
value2: array.reverse(array.reverse('array')) // [1, 2, 3]wraps Array.prototype.slice(), allows composing
array: [1, 2, 3],
value1: array.slice('array', 1), // [2, 3]
value2: array.slice('array', difference('array.length', 1)) // [3]sorts the given array of objects by key
array1: Ember.A([{ key: 'abc' }, { key: 'xyz' }]),
value1: array.sortBy('array1', 'key'), // [{ key: 'abc' }, { key: 'xyz' }]
value2: array.sortBy('array1', 'key:desc'), // [{ key: 'xyz' }, { key: 'abc' }]combines the functionality of both Array.prototype.sort() and Ember.computed.sort
array1: Ember.A(['xyz', 'abc']),
array2: Ember.A([{ key: 'abc' }, { key: 'xyz' }]),
value1: array.sort('array1'), // ['abc', 'xyz']
value2: array.sort('array2', ['key:desc']), // [{ key: 'xyz' }, { key: 'abc' }]
value3: array.sort('array2', (a, b) => a.key < b.key), // [{ key: 'xyz' }, { key: 'abc' }]wraps Ember.Array.uniqBy, allows composing
array: Ember.A([{ test: 1 }, { test: 2 }, { test: 2 }]),
key: 'test',
value: array.uniqBy('array', 'key') // [{ test: 1 }, { test: 2 }]wraps Ember.Array.uniq, allows composing
array: Ember.A([1, 2, 2]),
value: array.uniq('array') // [1, 2]wraps Ember.Enumerable.without, allows composing
array: Ember.A([1, 2, 3]),
referenceValue: 3,
value1: array.without('array', 'referenceValue'), // [1, 2]
value2: array.without('array', 2), // [1, 3]
value3: array.without('array', array.objectAt(1)) // [1, 3]same as Ember.computed.bool, but allows composing
source1: null,
source2: 'my value 1',
source3: { source: 'source3' },
value1: bool('source1'), // false
value2: bool('source2'), // true
value3: bool('source3'), // truesame as Ember.computed.collect, but allows composing
source1: 'my value 1',
source2: 'my value 2',
value: collect('source1', collect('source2')) // ['my value 1', ['my value 2']]implements the ternary operator, allows composing
condition1: true,
condition2: false,
expr1: 'my value 1',
expr2: 'my value 2',
value1: conditional('condition1', 'expr1', 'expr2'), // 'my value 1'
value2: conditional('condition2', 'expr1', 'expr2'), // 'my value 2'
value3: conditional(or('condition1', 'condition2'), raw('my value 1'), raw('my value 2')) // 'my value 1'true if source is undefined
source1: undefined,
source2: false,
source3: 'my value',
value1: defaultTrue('source1'), // true
value2: defaultTrue('source2'), // false
value3: defaultTrue('source3') // 'my value'subtracts numbers
source1: 3,
source2: 2,
source3: 1,
value1: difference('source1', 'source2', 'source3'), // 0
value2: difference('source1', collect('source2', 'source3')) // 2alias for quotient
alias for equal
like Ember.computed.equal, but uses dependent properties on both sides. allows N number of arguments.
source1: 'my value',
source2: 'my other value',
source3: 'my value',
value1: equal('source1', 'source2'), // false
value2: equal('source1', 'source3'), // true
value3: equal('source1', 'source2', 'source3') // falseget a variable property name from an object
key: 'modelProperty',
model: {
modelProperty: 'my value'
},
value1: getBy('model', 'key'), // 'my value'
value2: getBy('model', raw('modelProperty')) // 'my value'like Ember.computed.gt, but uses dependent properties on both sides
and allows composing
source1: 1,
source2: 2,
source3: 1,
value1: gt('source1', 'source2'), // false
value2: gt('source1', 'source3'), // false
value3: gt('source2', 'source3') // truelike Ember.computed.gte, but uses dependent properties on both sides
and allows composing
source1: 1,
source2: 2,
source3: 1,
value1: gte('source1', 'source2'), // false
value2: gte('source1', 'source3'), // true
value3: gte('source2', 'source3') // truebuild a hash out of computed properties, allows composing
source1: 'my value 1',
source2: 'my value 2',
value1: hash({
prop1: 'source1',
prop2: hash({
prop: 'source2'
})
}), // { prop1: 'my value 1', prop2: { prop: 'my value 2' } }
// you can also build the hash using property key names
value2: hash('source1', 'source2'), // { source1: 'my value 1', source2: 'my value 2' }
// or you can mix and match, the result will be merged
value3: hash('source1', { prop2: 'source2' }) // { source1: 'my value 1', prop2: 'my value 2' }wraps Ember.isEmpty
sourceString1: '',
sourceString2: 'foobar',
sourceArray1: [],
sourceArray2: [1, 2, 3],
sourceObject1: {},
sourceObject2: { size: 0 },
valueString1: isEmpty('sourceString1'), // true
valueString2: isEmpty('sourceString2'), // false
valueArray1: isEmpty('sourceArray1'), // true
valueArray2: isEmpty('sourceArray2'), // false
valueObject1: isEmpty('sourceObject1'), // false
valueObject2: isEmpty('sourceObject2'), // true
valueObject1: isEmpty(collect(1, 2)), // false
valueObject1: isEmpty([]), // truewraps instanceof operator
key1: {},
key2: false,
key3: '',
value1: instanceOf('key1', Object), // true
value2: instanceOf(or('key2', 'key3'), String) // truelike Ember.computed.lt, but uses dependent properties on both sides
and allows composing
source1: 1,
source2: 2,
source3: 1,
value1: lt('source1', 'source2'), // true
value2: lt('source1', 'source3'), // false
value3: lt('source2', 'source3') // falselike Ember.computed.lte, but uses dependent properties on both sides
and allows composing
source1: 1,
source2: 2,
source3: 1,
value1: lte('source1', 'source2'), // true
value2: lte('source1', 'source3'), // true
value3: lte('source2', 'source3') // falseexposes all Math functions
source1: 2.2,
source2: 2.7,
value1: math.ceil('source1'), // 3
value2: math.floor(sum('source1', 'source2')) // 4the modulus operator
number1: 123,
number2: 45,
example: mod('number1', 'number2'), // 33
composingExample: mod(sum('number1', 'number2'), 39) // 12alias for product
applies logical NAND operation
sourceTrue: true,
sourceFalse: false,
value1: nand('sourceFalse', 'sourceFalse', 'sourceFalse'), // true
value2: nand('sourceFalse', 'sourceTrue', 'sourceFalse'), // true
value3: nand('sourceTrue', 'sourceTrue', 'sourceTrue') // falsealias for notEqual
applies logical NOR operation
sourceTrue: true,
sourceFalse: false,
value1: nor('sourceFalse', 'sourceFalse', 'sourceFalse'), // true
value2: nor('sourceFalse', 'sourceTrue', 'sourceFalse'), // false
value3: nor('sourceTrue', 'sourceTrue', 'sourceTrue') // falsesame as Ember.computed.not, but allows composing
source1: true,
source2: false,
value1: not('source1'), // false
value2: not(and('source1', 'source2')) // truenegation of isEmpty
sourceString1: '',
sourceString2: foobar,
sourceArray1: [],
sourceArray2: [1, 2, 3],
sourceObject1: {},
sourceObject2: { size: 0 },
valueString1: notEmpty('sourceString1'), // false
valueString2: notEmpty('sourceString2'), // true
valueArray1: notEmpty('sourceArray1'), // false
valueArray2: notEmpty('sourceArray2'), // true
valueObject1: notEmpty('sourceObject1'), // true
valueObject2: notEmpty('sourceObject2'), // false
valueObject1: notEmpty(collect(1, 2)), // true
valueObject1: notEmpty([]) // falsethe inverse of equal, allows composing
source1: 'my value',
source2: 'my other value',
source3: 'my value',
value1: notEqual('source1', 'source2'), // true
value2: notEqual('source1', 'source3'), // false
value3: notEqual('source1', 'source2', 'source3') // truewraps Number, allows composing
prop: true,
example: number('prop'), // 1
composingExample: sum(collect(8, number('prop'))) // 9same as Ember.computed.or, but allows composing
source1: true,
source2: false,
source3: true,
value1: or('source1', 'source2', 'source3'), // true
value2: or(not('source1'), 'source2', not('source3')) // falsewraps parseFloat, allows composing
string1: '12.34',
string2: '12',
string3: '34',
example: parseFloat('string1'), // 12.34
composingExample: parseFloat(tag`${'string2'}.${'string3'}`) // 12.34wraps parseInt, allows composing
string: '123',
example: parseInt('string'), // 123
composingExample: parseInt(substr('string', 1), 8) // 19multiplies numbers
source1: 1,
source2: 2,
source3: 3,
value1: product('source1', 'source2', 'source3'), // 6
value2: product('source1', collect('source2', 'source3')) // 6combines promises using RSVP.all
promise1: computed(function() {
return RSVP.resolve('value1');
}),
promise2: computed(function() {
return RSVP.resolve('value2');
}),
promise: promise.all('promise1', 'promise2') // resolves to ['value1', 'value2']wraps a promise in the equivalent of DS.PromiseArray (ArrayProxy and PromiseProxyMixin)
productsPromise: computed(function() {
return this.store.findAll('product');
}),
products: promise.array('productsPromise')can also wrap a computed property
products: promise.array(computed(function() {
return this.store.findAll('product');
}))combines promises using RSVP.hash
promise1: computed(function() {
return RSVP.resolve('value1');
}),
promise2: computed(function() {
return RSVP.resolve('value2');
}),
promise: promise.hash('promise1', 'promise2') // resolves to { promise1: 'value1', promise2: 'value2' }wraps a promise in the equivalent of DS.PromiseObject (ObjectProxy and PromiseProxyMixin)
productPromise: computed(function() {
return this.store.findRecord('product', 1);
}),
product: promise.object('productPromise')can also wrap a computed property
product: promise.object(computed(function() {
return this.store.findRecord('product', 1);
}))wraps a value in an RSVP.resolve
key1: 'my value',
promise1: promise.resolve('key1'), // a resolved promise if you need it
key2: computed(function() {
return this.store.findRecord('user');
}),
promise2: promise.resolve(conditional('someBool', 'key1', 'key2')) // resolve an object if you don't know if it is a promise or notcalls .then() on a promise and then .get on the result
key: 'firstName',
userPromise: computed(function() {
return this.store.findRecord('user'); // { firstName: 'Mary' }
}),
firstName: promise.then('userPromise', 'key') // 'Mary'divides numbers
source1: 3,
source2: 2,
source3: 1,
value1: quotient('source1', 'source2', 'source3'), // 1.5
value2: quotient('source1', collect('source2', 'source3')) // 1.5wraps Ember.String.camelize, allows composing
originalValue: 'test-string',
newValue: string.camelize('originalValue') // 'testString'wraps Ember.String.capitalize, allows composing
originalValue: 'test string',
newValue: string.capitalize('originalValue') // 'Test string'wraps Ember.String.classify, allows composing
originalValue: 'test string',
newValue: string.classify('originalValue') // 'TestString'wraps Ember.String.dasherize, allows composing
originalValue: 'TestString',
newValue: string.dasherize('originalValue') // 'test-string'wraps Ember.String.decamelize, allows composing
originalValue: 'TestString',
newValue: string.decamelize('originalValue') // 'test_string'wraps Ember.Handlebars.Utils.escapeExpression, allows composing
originalValue: '<input>',
newValue: string.escapeExpression('originalValue') // '<input>'wraps Ember.String.htmlSafe, allows composing
originalValue: '<input>',
newValue: string.htmlSafe('originalValue') // will not be escapedwraps String.prototype.indexOf(), allows composing
string: '121',
value: '1',
example: string.indexOf('string', 'value'), // 0
composingExample: string.indexOf(substr('string', 1), raw('1')) // 1wraps Ember.String.isHTMLSafe, allows composing
source1: '<input>',
source2: string.htmlSafe('<input>'),
value1: string.isHtmlSafe('source1'), // false
value2: string.isHtmlSafe('source2') // truewraps String.prototype.lastIndexOf(), allows composing
string: '121',
value: '1',
example: string.lastIndexOf('string', 'value'), // 2
composingExample: string.lastIndexOf(substr('string', 0, 2), raw('1')) // 0wraps String.prototype.length, allows composing
string1: 'abc',
string2: 'xyz',
example: string.length('string1'), // 3
composingExample: string.length(tag`${'string1'}${'string2'}`) // 6wraps String.prototype.match, allows composing
string1: 'abc',
string2: 'xyz',
regex1: /abc/,
regex2: /xyz/,
example: string.match('string1', 'regex1'), // ['abc']
example: string.match('string1', 'regex2'), // null
composingExample: string.match(tag`${'string1'}${'string2'}`, 'regex2') // ['xyz']wraps String.prototype.replace, allows composing
string: 'abc',
substr: 'bc',
newSubstr: 'cb',
value1: string.replace('string', 'substr', 'newSubstr'), // 'acb'
value2: string.replace('string', 'substr', string.toUpper('newSubstr')) // 'aCB'wraps String.prototype.split, allows composing
source: 'val1,val2',
key: ',',
value1: string.split('source', 'key'), // ['val1', 'val2']
value2: string.split('source', raw(',')) // ['val1', 'val2']wraps String.prototype.substr(), allows composing
string1: 'abcxyz',
string2: 'abc',
string3: 'xyz',
example: string.substr('string1', 2, 2), // 'cx'
composingExample: string.substr(tag`${'string2'}${'string3'}`, 2, 2) // 'cx'wraps String.prototype.substring(), allows composing
string1: 'abcxyz',
string2: 'abc',
string3: 'xyz',
example: string.substring('string1', 2, 4), // 'cx'
composingExample: string.substring(tag`${'string2'}${'string3'}`, 2, 4) // 'cx'capitalizes words, allows composing
originalValue: 'james mcAvoy',
newValue: string.titleize('originalValue') // 'James Mcavoy'wraps String.prototype.toLowerCase(), allows composing
originalValue: 'TestString',
newValue: string.toLower('originalValue') // 'teststring'wraps String.prototype.toUpperCase(), allows composing
originalValue: 'TestString',
newValue: string.toUpper('originalValue') // 'TESTSTRING'wraps String.prototype.trim(), allows composing
originalValue: ' TestString ',
newValue: string.trim('originalValue') // 'TestString'wraps Ember.String.underscore, allows composing
originalValue: 'TestString',
newValue: string.underscore('originalValue') // 'test_string'alias for difference
adds numbers
source1: 1,
source2: 2,
source3: 3,
value1: sum('source1', 'source2', 'source3'), // 6
value2: sum('source1', collect('source2', 'source3')) // 6use a tagged template literal as a computed macro, allows composing
source: 'two',
value1: tag`one ${'source'} three`, // 'one two three'
value2: tag`one ${toUpper('source')} three` // 'one TWO three'calls toString with args on whatever you provide
key1: {},
key2: 253,
key3: 254,
value1: toStr('key1'), // '[object Object]'
value2: toStr(math.max('key2', 'key3'), 16) // 'fe'alias for toStr
The toString name conflicts with window.toString and breaks Babel, which means you need to do something like this:
import { toString as toStr } from 'ember-awesome-macros';That's why we provide the toStr alias.
wraps typeOf operator
key1: {},
key2: false,
key3: '',
value1: typeOf('key1'), // 'object'
value2: typeOf(or('key2', 'key3')) // 'string'macro version of {{unless}} and the inverse of conditional, allows composing
condition1: false,
condition2: true,
expr1: 'my value 1',
expr2: 'my value 2',
value1: unless('condition1', 'expr1', 'expr2'), // 'my value 1'
value2: unless('condition2', 'expr1', 'expr2'), // 'my value 2'
value3: unless(and('condition1', 'condition2'), raw('my value 1'), raw('my value 2')) // 'my value 1'applies logical XNOR operation
sourceTrue: true,
sourceFalse: false,
value1: xnor('sourceFalse', 'sourceFalse', 'sourceFalse'), // true
value2: xnor('sourceFalse', 'sourceTrue', 'sourceFalse'), // false
value3: xnor('sourceTrue', 'sourceTrue', 'sourceTrue') // trueapplies logical XOR operation
sourceTrue: true,
sourceFalse: false,
value1: xor('sourceFalse', 'sourceFalse', 'sourceFalse'), // false
value2: xor('sourceFalse', 'sourceTrue', 'sourceFalse'), // true
value3: xor('sourceTrue', 'sourceTrue', 'sourceTrue') // falseSee the Contributing guide for details.
This project is licensed under the MIT License.
