ember-awesome-macros

by kellyselden

A collection of Ember computed macros

208 Stars 33 Forks Last release: Not found MIT License 657 Commits 87 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

ember-awesome-macros

npm version Build Status dependencies Status devDependencies Status Ember Observer Score

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)) // true

Three 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.

Introduction Video

Ember Awesome Macros

Compatibility

  • Ember.js v3.8 or above
  • Ember CLI v2.13 or above
  • Node.js v8 or above

Installation

ember install ember-awesome-macros

Usage

import nameOfMacro from 'ember-awesome-macros/name-of-macro';
// or
import { nameOfMacro } from 'ember-awesome-macros';

Macro list

Array
Boolean
Comparison
Number
Object
Math
Promise
String

Custom macros

See [https://github.com/kellyselden/ember-macro-helpers#custom-macros].

Details

add

alias for

sum

and

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')) // true
array.any

wraps

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) // false
array.compact

wraps

Ember.Array.compact
, allows composing

array: Ember.A([1, 2, null]),
value: array.compact('array') // [1, 2]
array.concat

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]
array.every

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) // false
array.filterBy

wraps

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 }]
array.filter

wraps

Ember.Array.filter
, allows composing

array: Ember.A([{ test: 1 }, { test: 2 }]),
value: array.filter('array', item => item.test === 2) // [{ test: 2 }]
array.findBy

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 }
array.find

wraps

Ember.Array.find
, allows composing

array: Ember.A([{ test: 1 }, { test: 2 }]),
value: array.find('array', item => item.test === 2) // { test: 2 }
array.first

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'
array.groupBy

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 }] } ] */

array.includes

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')) // true
array.indexOf

wraps

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') // 2
array.invoke

wraps

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'
array.isAny

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') // false
array.isEvery

wraps

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') // false
array.join

wraps

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'
array.lastIndexOf

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') // 2
array.last

get the last item of an array

array: ['1', '2'],
string: '1, 2',
example: array.last('array'), // '2'
composingExample: array.last(split('string', raw(', '))) // '2'
array.length

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(','))) // 2
array.mapBy

wraps

Ember.Array.mapBy
, allows composing

array: Ember.A([{ test: 1 }, { test: 2 }]),
key: 'test',
value: array.mapBy('array', 'key') // [1, 2]
array.map

wraps

Ember.Array.map
, allows composing

array: Ember.A([{ test: 1 }, { test: 2 }]),
value: array.map('array', item => item.test) // [1, 2]
array.objectAt

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'
array.reduce

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]

array.rejectBy

wraps

Ember.Array.rejectBy
, allows composing

array: Ember.A([{ test: 1 }, { test: 2 }]),
key: 'test',
value: array.rejectBy('array', 'key', 2) // [{ test: 1 }]
array.reverse

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]
array.slice

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]
array.sortBy

sorts the given array of objects by key

js
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' }]
array.sort

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' }]
array.uniqBy

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 }]
array.uniq

wraps

Ember.Array.uniq
, allows composing

array: Ember.A([1, 2, 2]),
value: array.uniq('array') // [1, 2]
array.without

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]
bool

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'), // true
collect

same 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']]
conditional

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'
defaultTrue

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'
difference

subtracts numbers

source1: 3,
source2: 2,
source3: 1,
value1: difference('source1', 'source2', 'source3'), // 0
value2: difference('source1', collect('source2', 'source3')) // 2
divide

alias for

quotient

eq

alias for

equal

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') // false
getBy

get 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'
gt

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') // true
gte

like

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') // true
hash

build 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' }

isEmpty

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([]), // true

instanceOf

wraps

instanceof
operator

key1: {},
key2: false,
key3: '',
value1: instanceOf('key1', Object), // true
value2: instanceOf(or('key2', 'key3'), String) // true
lt

like

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') // false
lte

like

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') // false
math

exposes all

Math
functions

source1: 2.2,
source2: 2.7,
value1: math.ceil('source1'), // 3
value2: math.floor(sum('source1', 'source2')) // 4
mod

the modulus operator

number1: 123,
number2: 45,
example: mod('number1', 'number2'), // 33
composingExample: mod(sum('number1', 'number2'), 39) // 12
multiply

alias for

product

nand

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') // false

neq

alias for

notEqual

nor

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') // false

not

same as

Ember.computed.not
, but allows composing
source1: true,
source2: false,
value1: not('source1'), // false
value2: not(and('source1', 'source2')) // true
notEmpty

negation 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([]) // false

notEqual

the 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') // true
number

wraps

Number
, allows composing

prop: true,
example: number('prop'), // 1
composingExample: sum(collect(8, number('prop'))) // 9
or

same 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')) // false
parseFloat

wraps

parseFloat
, allows composing

string1: '12.34',
string2: '12',
string3: '34',
example: parseFloat('string1'), // 12.34
composingExample: parseFloat(tag`${'string2'}.${'string3'}`) // 12.34
parseInt

wraps

parseInt
, allows composing

string: '123',
example: parseInt('string'), // 123
composingExample: parseInt(substr('string', 1), 8) // 19
product

multiplies numbers

source1: 1,
source2: 2,
source3: 3,
value1: product('source1', 'source2', 'source3'), // 6
value2: product('source1', collect('source2', 'source3')) // 6
promise.all

combines 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']
promise.array

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');
}))
promise.hash

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' }
promise.object

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);
}))
promise.resolve

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 not

promise.then

calls

.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'

quotient

divides numbers

source1: 3,
source2: 2,
source3: 1,
value1: quotient('source1', 'source2', 'source3'), // 1.5
value2: quotient('source1', collect('source2', 'source3')) // 1.5
string.camelize

wraps

Ember.String.camelize
, allows composing

originalValue: 'test-string',
newValue: string.camelize('originalValue') // 'testString'
string.capitalize

wraps

Ember.String.capitalize
, allows composing

originalValue: 'test string',
newValue: string.capitalize('originalValue') // 'Test string'
string.classify

wraps

Ember.String.classify
, allows composing

originalValue: 'test string',
newValue: string.classify('originalValue') // 'TestString'
string.dasherize

wraps

Ember.String.dasherize
, allows composing

originalValue: 'TestString',
newValue: string.dasherize('originalValue') // 'test-string'
string.decamelize

wraps

Ember.String.decamelize
, allows composing

originalValue: 'TestString',
newValue: string.decamelize('originalValue') // 'test_string'
string.escapeExpression

wraps

Ember.Handlebars.Utils.escapeExpression
, allows composing
originalValue: '',
newValue: string.escapeExpression('originalValue') // '<input>'
string.htmlSafe

wraps

Ember.String.htmlSafe
, allows composing

originalValue: '',
newValue: string.htmlSafe('originalValue') // will not be escaped
string.indexOf

wraps

String.prototype.indexOf()
, allows composing

string: '121',
value: '1',
example: string.indexOf('string', 'value'), // 0
composingExample: string.indexOf(substr('string', 1), raw('1')) // 1
string.isHtmlSafe

wraps

Ember.String.isHTMLSafe
, allows composing

source1: '',
source2: string.htmlSafe(''),
value1: string.isHtmlSafe('source1'), // false
value2: string.isHtmlSafe('source2') // true
string.lastIndexOf

wraps

String.prototype.lastIndexOf()
, allows composing

string: '121',
value: '1',
example: string.lastIndexOf('string', 'value'), // 2
composingExample: string.lastIndexOf(substr('string', 0, 2), raw('1')) // 0
string.length

wraps

String.prototype.length
, allows composing

string1: 'abc',
string2: 'xyz',
example: string.length('string1'), // 3
composingExample: string.length(tag`${'string1'}${'string2'}`) // 6
string.match

wraps

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']
string.replace

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'
string.split

wraps

String.prototype.split
, allows composing

source: 'val1,val2',
key: ',',
value1: string.split('source', 'key'), // ['val1', 'val2']
value2: string.split('source', raw(',')) // ['val1', 'val2']
string.substr

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'
string.substring

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'
string.titleize

capitalizes words, allows composing

originalValue: 'james mcAvoy',
newValue: string.titleize('originalValue') // 'James Mcavoy'
string.toLower

wraps

String.prototype.toLowerCase()
, allows composing

originalValue: 'TestString',
newValue: string.toLower('originalValue') // 'teststring'
string.toUpper

wraps

String.prototype.toUpperCase()
, allows composing

originalValue: 'TestString',
newValue: string.toUpper('originalValue') // 'TESTSTRING'
string.trim

wraps

String.prototype.trim()
, allows composing

originalValue: ' TestString ',
newValue: string.trim('originalValue') // 'TestString'
string.underscore

wraps

Ember.String.underscore
, allows composing

originalValue: 'TestString',
newValue: string.underscore('originalValue') // 'test_string'
subtract

alias for

difference

sum

adds numbers

source1: 1,
source2: 2,
source3: 3,
value1: sum('source1', 'source2', 'source3'), // 6
value2: sum('source1', collect('source2', 'source3')) // 6
tag

use 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'
toStr

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'
toString

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.

typeOf

wraps

typeOf
operator

key1: {},
key2: false,
key3: '',
value1: typeOf('key1'), // 'object'
value2: typeOf(or('key2', 'key3')) // 'string'
unless

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'
xnor

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') // true

xor

applies

logical XOR
operation

sourceTrue: true,
sourceFalse: false,

value1: xor('sourceFalse', 'sourceFalse', 'sourceFalse'), // false value2: xor('sourceFalse', 'sourceTrue', 'sourceFalse'), // true value3: xor('sourceTrue', 'sourceTrue', 'sourceTrue') // false

Contributing

See the Contributing guide for details.

License

This project is licensed under the MIT License.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.