0.0.1 • Published 7 years ago

ember-compose-methods v0.0.1

Weekly downloads
1
License
MIT
Repository
github
Last release
7 years ago

ember-compose-methods

Methods to make the code more functional and easy to handle.

Installation

ember install ember-compose-methods

Compose Method

compose make a pipeline to execute functions in sequence and return a promise resolving the result.

Usage

Pass the functions to compose in reverse sequence of execution, just to keep the same code visual sequence. If your sequence is fc3(fc2(fc1(...))) it has to be compose(fc3, fc2, fc1).

/* controllers/application.js */
import Ember from 'ember';
import compose from 'ember-compose-methods/utils/compose';

export default Ember.Controller.extend({

	value: undefined,
	inputValue: undefined,
	outputValue: undefined,
	
	actions: {
		calculate(value) {
			let input = parseFloat(value);
			Ember.set(this, 'inputValue', input);

			const fc1 = x => x + 1;
			const fc2 = x => x * 2;
			const fc3 = x => x - 3;
			const c = compose(fc3, fc2, fc1);

			c(input).then(r => Ember.set(this, 'outputValue', r));
		},
	},

});
{{!-- templates/application.hbs --}}
Enter a number: 
{{input type="number" value=value}}
<button {{action 'calculate' value}}>Calculate</button>

<br>Input: {{inputValue}}
<br>Output: {{outputValue}}

Result
npm.io

Promises

It's possible to mix functions returning values or promises.
compose waits a promise resolve to fire the next function.

/* controllers/application.js */
import Ember from 'ember';
import compose from 'ember-compose-methods/utils/compose';

export default Ember.Controller.extend({

	value: undefined,
	inputValue: undefined,
	outputValue: undefined,
	
	actions: {
		calculate(value) {
			let input = parseFloat(value);
			Ember.set(this, 'inputValue', input);

			const fc1 = x => x + 1;
			const fc2 = x => Promise.resolve(x * 2);
			const fc3 = x => x - 3;
			const c = compose(fc3, fc2, fc1);

			c(input).then(r => Ember.set(this, 'outputValue', r));
		},
	},

});

Result
npm.io

Functions in Objects

Sometimes the function is inside a object. Let's say you have some products models and want to sum the total. The attribute sumToTotal is responsible for that, so use it as the first param on compose method.

/* models/product.js */
import DS from 'ember-data';

export default DS.Model.extend({

	name: DS.attr('string'),
	price: DS.attr('number'),
	discount: DS.attr('number'),
	taxes: DS.attr('number'),

	getDiscount: discount => 1 - (discount / 100),
	getTaxes: taxes => (taxes / 100) + 1,
	getPrice: (price, discount, taxes) => price * discount * taxes,

	sumToTotal(subtotal = 0) {
		const price = Ember.get(this, 'price')
			, discount = this.getDiscount(Ember.get(this, 'discount'))
			, taxes = this.getTaxes(Ember.get(this, 'taxes'))
			, total = this.getPrice(price, discount, taxes);

		return subtotal + total;
	},

});
/* controllers/application.js */
import Ember from 'ember';
import compose from 'ember-compose-methods/utils/compose';

export default Ember.Controller.extend({
	
	init() {
		this._super(...arguments);

		this.store.createRecord('product', {
		    name: 'Product 1', 
		    price: 100, 
		    discount: 10, 
		    taxes: 0
		}); //total = 90
		
		this.store.createRecord('product', {
		    name: 'Product 2', 
		    price: 50, 
		    discount: 5, 
		    taxes: 10
		}); //total = 52,25
		
		this.store.createRecord('product', {
		    name: 'Product 3', 
		    price: 150, 
		    discount: 15, 
		    taxes: 30
		}); //total = 165,75

		const products = this.store.peekAll('product').toArray();
		const c = compose('sumToTotal', ...products);
		c().then(r => console.log('Total: ', r));
	},

});

Result

> Total: 308
//0 + 90 = 90 + 52,25 = 142,25 + 165,75 = 308
Values, Promises and Objects

You can mix all of them!

/* controllers/application.js */
import Ember from 'ember';
import compose from 'ember-compose-methods/utils/compose';

export default Ember.Controller.extend({

	value: undefined,
	inputValue: undefined,
	outputValue: undefined,
	
	actions: {
		calculate(value) {
			let input = parseFloat(value);
			Ember.set(this, 'inputValue', input);

			const fc1 = x => x + 1;
			const fc2 = {'calculate': x => x * 2};
			const fc3 = {'calculate': x => Promise.resolve(x - 3)};
			const c = compose('calculate', fc3, fc2, fc1);

			c(input).then(r => Ember.set(this, 'outputValue', r));
		},
	},

});

Result
npm.io