How can I add a console log in this function? - javascript

Pretty straight forward question, I'm just trying to get a console log in this es6 function.
const testLinesSelector = state => state.tests.testLines || [];
I've tried:
const testLinesSelector = state => {
console.log('INSIDE THE SELECTOR ===> ');
return {state.tests.testLines || [] }
};

Remove the braces in your return statement, like so:
const testLinesSelector = state => {
console.log('INSIDE THE SELECTOR ===> ');
return state.tests.testLines || [];
};
As a side-note, I noticed a lot of ES6 code uses function-variables or function-properties instead of just functions - is there a reason you don’t do this instead?
function testLinesSelector( state ) {
console.log('INSIDE THE SELECTOR ===> ');
return state.tests.testLines || [];
};

Another approach you might consider automating your code using Function.name - though this requires using a named function (a la function foobar() { ... }). There are techniques to get the "name" of an anonymous function or arrow-function in JavaScript but they're more involved and may not be compatible with the "established patterns in the code" you're working with.
But here's how you can do it with named functions:
function annotate( func ) {
return ( ...args ) => {
console.log( func.name ); // `Function.name` is supported in ES6.
return func( ...args );
};
}
const testLinesSelector = annotate( function testLinesSelector( state ) { return state.tests.testLines || [] } );

Related

Can method chaining be implemented the way built-in functions in Javascript are implemented?

I think there is something that i'm missing about method chaining. To me it feels incomplete.
Method chaining works by having each method return this so that another method on that object can be called. However, the fact that the return value is this and not the result of the function seems inconvenient to me.
Here is a simple example.
const Obj = {
result: 0,
addNumber: function (a, b) {
this.result = a + b;
return this;
},
multiplyNumber: function (a) {
this.result = this.result * a;
return this;
},
}
const operation = Obj.addNumber(10, 20).multiplyNumber(10).result
console.log(operation)
key points:
Every method in the chain Obj.addNumber(10, 20).multiplyNumber(10) returns this.
The last part of the chain .result is the one that returns a value other than this.
The problem with this approach is that it require you to tack on a property / method to get a value at the end other thanthis.
Compare this with built-in functions in JavaScript.
const str = " SomE RandoM StRIng "
console.log(str.toUpperCase()) // " SOME RANDOM STRING "
console.log(str.toUpperCase().trim()) // "SOME RANDOM STRING"
console.log(str.toUpperCase().trim().length) // 18
key points:
Each function in the chain returns the result of the function not this (maybe this is done under the hood)
No property / method is required at the end of the chain just to get the result.
Can we implement method chaining to behave the way built-in functions in Javascript behave?
First of all, each of your console.log doesn't return properly:
console.log(str.toUpperCase.trim) //undefined
It returns undefined because str.toUpperCase returns the function object and does not execute the function itself so it won't work
The only correct usage is
console.log(str.toUpperCase().trim()
Now about your question, it is pretty easy to do it without a result and it is much more efficient.
Everything in javascript has a method called valueOf(), here is my example of calling everything like that for numbers, though I prefer just making functions instead of Objects.
const Obj = {
addNumber: function (a = 0) {
return a + this.valueOf();
},
multiplyNumber: function (a = 1) {
return a*this.valueOf();
},
}
const nr = 2;
Object.keys(Obj).forEach(method => {
Number.prototype[method] = Obj[method];
})
console.log(Number.prototype); // will print out addNumber and multiplyNumber
// Now You can call it like this
console.log(nr.addNumber().multiplyNumber()); // Prints out 2 because it becomes (nr+0)*1
console.log(nr.addNumber(3).multiplyNumber(2)) // Prints out 10;
I think you are misunderstanding what method chaining actually is. It is simply a shorthand for invoking multiple methods without storing each intermediate result in a variable. In other words, it is a way of expressing this:
const uppercase = " bob ".toUpperCase()
const trimmed = uppercase.trim()
as this
const result = " bob ".toUpperCase().trim()
Nothing special is happening. The trim method is simply being called on the result of " bob ".toUpperCase(). Fundamentally, this boils down to operator precedence and the order of operations. The . operator is an accessor, and is evaluated from left to right. This makes the above expression equivalent to this (parens used to show order of evaluation):
const result = (" bob ".toUpperCase()).trim()
This happens regardless of what is returned by each individual method. For instance, I could do something like this:
const result = " bob ".trim().split().map((v,i) => i)
Which is equivalent to
const trimmed = " bob ".trim()
const array = trimmed.split() //Note that we now have an array
const indexes = array.map((v,i) => i) //and can call array methods
So, back to your example. You have an object. That object has encapsulated a value internally, and adds methods to the object for manipulating the results. In order for those methods to be useful, you need to keep returning an object that has those methods available. The simplest mechanism is to return this. It also may be the most appropriate way to do this, if you actually are trying to make the object mutable. However, if immutability is an option, you can instead instantiate new objects to return, each of which have the methods you want in the prototype. An example would be:
function MyType(n) {
this.number = n
}
MyType.prototype.valueOf = function() {
return this.number
}
MyType.prototype.add = function(a = 0) {
return new MyType(a + this)
}
MyType.prototype.multiply = function(a = 1) {
return new MyType(a * this)
}
const x = new MyType(1)
console.log(x.add(1)) // { number: 2 }
console.log(x.multiply(2)) // { number: 2 }
console.log(x.add(1).multiply(2)) // { number: 4 }
console.log(x.add(1).multiply(2) + 3) // 7
The key thing to note about this is that you are still using your object, but the valueOf on the prototype is what allows you to directly utilize the number as the value of the object, while still making the methods available. This is shown in the last example, where we directly add 3 to it (without accessing number). It is leveraged throughout the implementation by adding this directly to the numeric argument of the method.
Method chaining is the mechanism of calling a method on another method of the same object in order to get a cleaner and readable code.
In JavaScript method chaining most use the this keyword in the object's class in order to access its method (because the this keyword refers to the current object in which it is called)
When a certain method returns this, it simply returns an instance of the object in which it is returned, so in another words, to chain methods together, we must make sure that each method we define has a return value so that we can call another method on it.
In your code above, the function addNumber returns the current executing context back from the function call. The next function then executes on this context (referring to the same object), and invokes the other functions associated with the object. it's is a must for this chaining to work. each of the functions in the function chaining returns the current Execution Context. the functions can be chained together because the previous execution returns results that can be processed further on.
This is part of the magic and uniqueness of JavaScript, if you're coming from another language like Java or C# it may look weird for you, but the this keyword in JavaScript behaves differently.
You can avoid the necessity of this and be able to return a value implicitly, using a Proxy object with a get-trap.
Here you find a more generic factory for it.
const log = Logger();
log(`<code>myNum(42)
.add(3)
.multiply(5)
.divide(3)
.roundUp()
.multiply(7)
.divide(12)
.add(-1.75)</code> => ${
myNum(42)
.add(3)
.multiply(5)
.divide(3)
.roundUp()
.multiply(7)
.divide(12)
.add(-1.75)}`,
);
log(`\n<code>myString(\`hello world\`)
.upper()
.trim()
.insertAt(6, \`cruel coding \`)
.upper()</code> => ${
myString(`hello world`)
.upper()
.trim()
.insertAt(6, `cruel coding `)
.upper()
}`);
log(`<br><code>myString(\`border-top-left-radius\`).toUndashed()</code> => ${
myString(`border-top-left-radius`).toUndashed()}`);
// the proxy handling
function proxyHandlerFactory() {
return {
get: (target, prop) => {
if (prop && target[prop]) {
return target[prop];
}
return target.valueOf;
}
};
}
// a wrapped string with chainable methods
function myString(str = ``) {
const proxyHandler = proxyHandlerFactory();
const obj2Proxy = {
trim: () => nwProxy(str.trim()),
upper: () => nwProxy(str.toUpperCase()),
lower: () => nwProxy(str.toLowerCase()),
insertAt: (at, insertStr) =>
nwProxy(str.slice(0, at) + insertStr + str.slice(at)),
toDashed: () =>
nwProxy(str.replace(/[A-Z]/g, a => `-${a.toLowerCase()}`.toLowerCase())),
toUndashed: () => nwProxy([...str.toLowerCase()]
.reduce((acc, v) => {
const isDash = v === `-`;
acc = { ...acc,
s: acc.s.concat(isDash ? `` : acc.nextUpcase ? v.toUpperCase() : v)
};
acc.nextUpcase = isDash;
return acc;
}, {
s: '',
nextUpcase: false
}).s),
valueOf: () => str,
};
function nwProxy(nwStr) {
str = nwStr || str;
return new Proxy(obj2Proxy, proxyHandler);
}
return nwProxy();
}
// a wrapped number with chainable methods
function myNum(n = 1) {
const proxyHandler = proxyHandlerFactory();
const obj2Proxy = {
add: x => nwProxy(n + x),
divide: x => nwProxy(n / x),
multiply: x => nwProxy(n * x),
roundDown: () => nwProxy(Math.floor(n)),
roundUp: () => nwProxy(Math.ceil(n)),
valueOf: () => n,
};
function nwProxy(nwN) {
n = nwN || n;
return new Proxy(obj2Proxy, proxyHandler);
}
return nwProxy();
}
// ---- for demo ---- //
function Logger() {
const report =
document.querySelector("#report") ||
document.body.insertAdjacentElement(
"beforeend",
Object.assign(document.createElement("pre"), {
id: "report"
})
);
return (...args) => {
if (!args.length) {
return report.textContent = ``;
}
args.forEach(arg =>
report.insertAdjacentHTML(`beforeEnd`,
`<div>${arg.replace(/\n/g, `<br>`)}</div>`)
);
};
}
body {
font: 12px/15px verdana, arial;
margin: 0.6rem;
}
code {
color: green;
}

destructuring props in component getting different result

New to react world, trying to learn destructuring, have been reading about it but stuck here,
if i do it like this function MList({action}) { // const data = [action];} i am just getting 'cameras'. So how to destructure and get same result as with props below
this is Mcard.js:
<Box pt={1}>
<MList
action="cameras"
/>
</Box>
This is inside MList komponent:
i want to destructure this code ( works gives 'name' and 'ident'):
function MList(props) {
const initialize = () => {
const data = props[props.action];
if (!data || data.length < 1) {
return;
}
data.map((e) => {
collapseStates["" + e.name + e.ident] = false;
return;
});
setCollapseS(collapseS);
};
}
I don't know React but destructuring the arguments should be something like the following
function MList({action, ...tail}) {
const initialize = () => {
const data = tail[action];
if (!data || data.length < 1) {
return;
}
data.map(({name, ident}) => {
collapseStates["" + name + ident] = false;
return;
});
setCollapseS(collapseS);
};
}
Also I would suggest using data.forEach instead of data.map if you don't need to save the result in another array
Nikita is correct about using props["action"] or props.action to grab the values. But you can actually destructure the props right inside of the function declaration like so:
function MList({ action, ...other props }) {
// Can now use action directly instead of props.action
}
It is also worth noting that array and object destructuring is not react specific, this is just how javascript works.
Edit: Accessing the action variable from here will give you "cameras" as a result because that is what you passed into the props

change the scope in this function to the invoker with jquery or vanilla javascript

Sample code with what I want to do is commented:
myObj.doSomething({
callbackFn: function( result ) {
if ( result && result.retval !== null )
{
// I want to assign the values on result.retval to myObj
// but `this` is not equal to myObj.
// is it correct to just do this?
myObj.some_val = result.some_val;
}
}
});
Normally with underscore, I'd use its _.bind() function to do this. The code I'm dealing with doesn't use underscore. What's the best way to do this with vanilla JS or jQuery?
JavaScript itself provides .bind:
myObj.doSomething({
callbackFn: function( result ) {
if ( result && result.retval !== null )
{
this.some_val = result.some_val;
}
}.bind(myObj); // <--
});
This is under the assumption that you cannot change the implementation of doSomething. If you can change it, see #10100111001's answer.
But you might as well use the code you currently have. I don't see a big benefit of using .bind here.
Just for fun, a simple version of.bind is pretty easy to implement yourself, should you find yourself in an environment that doesn't support it:
function bind(f, thisValue) {
return function() {
return f.apply(thisValue, arguments);
};
}
var boundF = bind(f, myObj);
You can also do something like this where you can call the callbackFn in doSomething with the proper this value.
var myObj = {};
myObj.doSomething = function (obj) {
obj.callbackFn.call(this, {some_val: "test"});
}
myObj.doSomething({
callbackFn: function( result ) {
if ( result && result.retval !== null )
{
// I want to assign the values on result.retval to myObj
// but `this` is not equal to myObj.
// is it correct to just do this?
this.some_val = result.some_val;
}
}
});
console.log(myObj);
with block is pretty much :
function( result ) {
if ( result && result.retval !== null )
{
with(myObj){
some_val = result.some_val; // Even,no Need "this"
}
}
}
Even, No need this

Rx.Observable.bindCallback with scope in rxjs

It seems in rxjs 4.x, Rx.Observable.fromCallback accept scope as the second parameter, but in 5.0, this method is changed to Rx.Observable.bindCallback and doesn't accept scope parameter. How to add scope parameter in bindCallback. For example in ES6.
class Test {
constructor(input) {
this.input = input;
}
callback(cb) {
return cb(this.input);
}
rx() {
// this works on rx 4.x
// var observable = Rx.Observable.fromCallback(this.callback, this)();
// this doesn't work, because this.callback function doesn't use original this, so cannot get this.input
var observable = Rx.Observable.bindCallback(this.callback)();
// Work around: Rx.Observable.bindCallback(this.callback)();
// var me = this;
// var observable = Rx.Observable.bindCallback((cb) => {me.callback(cb);})();
observable.subscribe(
input => console.log('get data => ' + input),
err => console.log('get error =>' + err),
() => console.log('complete')
);
}
}
new Test(100).rx();
There is an example at http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-bindCallback which shows how to do this.
Use bindCallback on object method
const boundMethod = Rx.Observable.bindCallback(someObject.methodWithCallback);
boundMethod.call(someObject) // make sure methodWithCallback has access to someObject
.subscribe(subscriber);
You can call it immediately without declaring a variable, and also pass args like this:
Rx.Observable.bindCallback(someObject.callback).call(someObject,<args>)
So to bind to this you can simply call
Rx.Observable.bindCallback(this.callback).call(this,<args>)
It works for me, when I add this to the constructor
constructor(input) {
this.input = input;
this.callback = this.callback.bind(this)
}

functional composition javascript

I'm trying to understand functional composition in Javascript and followed a talk which describes the compose function
I tried the following program which will accept a sentence, break it up into pieces (delimited by space) and use uppercase on each word and return an array of words.
function compose(f, g) {
"use strict";
return function() {
return f.call(this, g.apply(this,arguments));
}
}
var split = function (string, delim) {
"use strict";
return string.split(delim);
};
var uppercase = function (string) {
"use strict";
if (string instanceof Array) {
return string.map(function (x) {
return x.toString().toUpperCase();
});
} else {
return string.toString().toUpperCase();
}
//return string.toString().toUpperCase();
};
var myfunc = compose(uppercase,split);
var data = myfunc("Elementary! My dear Watson",/\s+/);
console.log(data);
Though I got what I wanted, but the code is ugly on following counts:
I've to re-define split and toUpperCase as I constantly got
"Reference error: toUpperCase not defined". Is it because they are
methods and not pure functions per se?
the uppercase method is ugly because it should receive just a single string so that it flips the case,but since I'm tokenizing it, this function receives an array and hence the ugly array check.
How can the code be improvised to have a "pipe of functions" viz. split -> map -> uppercase ?
Here is the same sort of code that you have which has been simplified a little. If this is the direction you want to take with your coding I cant recommend Javascript Allonge by Reg Braithwait enough, It completely changed the way I thought about writing code.
Hopefully this small example shows how to compose functions and how useful functional js is. Another big benefit is that if you are using pure functions that don't look to the outer scope you can easily debug issues as there is a dependable stream of function calls that you can follow.
Learning Functional enough to be able to understand it's basic concepts took me about 6 months and constant practice. but it was well worth the effort.
"use strict"; // you just need one use strict on the hholee file
// for compose you shouldn't really need to call or apply as this is always the window for a pure function
function compose(a, b) {
return function( c ) {
return a( b( c ) );
}
}
// split is now a simple function that takes a delimeter and returns a function that splits the string
function split(delim) {
return function( string ){
return string.split(delim);
}
};
// if you add a function mapper you can remove some of the complexity in uppercase
// and compose map with uppercase
function map( fn ){
return function( arr ){
return Array.prototype.map.call( arr, fn );
}
}
// this is now a very simple single responsibility function that can be composed
function uppercase(string) {
return string.toUpperCase();
};
var
splitBySpace = split(/\s+/),
arrToUpper = map(uppercase),
myfunc = compose(arrToUpper,splitBySpace);
console.log( arrToUpper(['one', 'two']) );
console.log( myfunc("Elementary! My dear Watson") );
// if you want to split on a different character you will need to create a new split function by currying a different delimeter
var
splitByChar = split(''),
splitByBang = split('!');
// you also don't have to compose the functions you can write them out normally but it is much harder to follow eg.
console.log( map(uppercase)(split('')("Elementary! My dear Watson") ) );
<script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script>
Here is a small example of how to get a fluent interface up and running covering the third part of your question. the key thing to take away is you create an object with new Obj and in the methods you need to return this to allow method chaining.
Functional Javascript cannot allow chaining methods as it has no internal state, you use functional js to decorate and mix other functions that can return either a value or another function.
// MyObj is declared within a module to make the internals private
var myObj = (function() {
// Constructor function
function MyObj(string, delim) {
this.input = string;
this.delim = delim;
}
// create the MyObj methods on it's prototype
// all methods have been decorated with the fluent function
MyObj.prototype = {
// split the input
split: fluent(function(delim) {
if( ! Array.isArray( this.input ) ){
this.input = this.input.split( delim != null ? delim : this.delim);
}
}),
// convert the text to uppercase
uppercase: fluent(function() {
if (Array.isArray(this.input)) {
this.input = this.input.map(function(string) {
return string.toUpperCase();
});
} else {
this.input = this.input.toUpperCase();
}
}),
// reverse the array
reverse: fluent(function(){
if( Array.isArray( this.input ) ){
this.input = this.input.reverse();
}
else {
this.input = this.input.split('').reverse().join('');
}
}),
// you will need a getter if you are using a fluent interface or decide what your end points will be
get: function() {
return this.input;
}
}
return function constructor(string, delim) {
return new MyObj(string, delim);
}
})();
// myObj is the function to create a MyObj
console.log( myObj );
console.log( myObj("Elementary! My dear Watson", /\s+/ ).split().uppercase().get() );
// with the code you can override the default delimeter
console.log( myObj("Elementary! My dear Watson", /\s+/ ).split('').uppercase().get() );
// run different methods
console.log( myObj("Elementary! My dear Watson", /\s+/ ).split().uppercase().reverse().get() );
// order no longer matters
console.log( myObj("Elementary! My dear Watson", /\s+/ ).reverse().uppercase().split().get() );
// MyObj also has an internal state so you can do
// functional decorator - this will make the prototype methods return a value or this
function fluent(method) {
return function() {
var ret = method.apply(this, arguments);
return ret != null
? ret
: this;
}
}
<script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script>
Functional composition is just when you take two or more functions, and make one a single function out of them. I've written up a pretty easy to follow explanation of composing functions that I think will clear up quite a few things for you.
What you want however is something very different, and is very straight forward in javascript
"Elementary! My dear Watson".split(/\s+/).map(val => val.toUpperCase());
or if you really want it as a function like you have above...
function myFunct(str, delim) {
str.split(delim).map(val => val.toUpperCase());
}
composing function allows reusability of functions. You can apply javascript reduce method to apply set of functions on data.
Lets start with a basic reduce sample. The following is set of functions to calculate sale price.
const SALES_TAX = 0.08;
const COUPON_CODES = {
AAAA: 0.1,
BBBB: 0.07,
CCCC: 0.15,
};
const shoppingtotal = shoppingCart =>
shoppingCart.reduce((acc, item) => {
acc += item.price * item.qty;
return acc;
}, 0);
const discount = couponCode => amount =>
amount * (1 - COUPON_CODES[couponCode]);
const tax = amt => amt * (1 + SALES_TAX);
I can create a compose as below
const compose = fns => input => fns.reduce((acc, fn) => fn(acc), input);
const calculatePayment = compose([shoppingtotal, discount('AAAA'), tax]);
Now to calculate price, I can call calculatePayment.
calculatePayment([
{
name: 'pencil',
price: 1,
qty: 2,
},
{
name: 'Pen',
price: 1.5,
qty: 20,
},
{
name: 'Eraser',
price: 0.25,
qty: 10,
}])
It is a sample. Like this, you can easily compose multiple functions and create new function definitions.

Categories