Pass additional parameters to bind? - javascript

I have two functions that look like this:
primaryImageLoaded () {
this.setState({primaryImageLoaded: true})
}
secondaryImageLoaded () {
this.setState({ secondaryImageLoaded: true })
}
They are called like this(using react):
onLoad={this.secondaryImageLoaded.bind(this)
This feels excessive and I would like to have just one function and pass the state-variable as a parameter, but how can I pass an additional argument to .bind? and is it possible to use a variable as key in the object i'm passing to setState?

You can pass additional arguments to bind that will be passed when your function is invoked:
this.secondaryImageLoaded.bind(this, arg1, arg2)
If you are using ECMAScript 2015 and onwards, you can use a variable as a key by wrapping it in square brackets:
this.setState({
[myVar]: value
});
So you could rewrite it to be more like:
function imageLoaded(which) {
this.setState({
[which]: true
});
}
onLoad={this.imageLoaded.bind(this, 'secondary')}

You can use arrow function for definition your function, and this way you don't need bind method.
secondaryImageLoaded = () => {
this.setState({ secondaryImageLoaded: true })
}
After that, in your jsx code:
onLoad={this.secondaryImageLoaded}
If you want know more about that you read this article

Related

Using a function inside a Vue method

How can I write a function instead of this Replace snippet and use it inside my checkAnswer method?
methods: {
checkAnswer: function () {
this.quiz.userInputArray = this.quiz.userAnswerArray.replace('Ğ','g')
.replace('Ü','u')
.replace('Ş','s')
.replace('I','i')
.replace('ç','c');
}
I want to be able to use it code like this:
this.quiz.userInputArray = this.quiz.userAnswerArray.replaceFunc()
you can create another method called replaceFunc
methods: {
replaceFunc(arr){
return arr.replace('Ğ','g')
.replace('Ü','u')
.replace('Ş','s')
.replace('I','i')
.replace('ç','c');
},
checkAnswer(){
this.quiz.userInputArray = this.replaceFunc(this.quiz.userAnswerArray);
}
}
Otherwise, if you insist on calling replaceFunc like this this.quiz.userAnswerArray.replaceFunc(), then you can read about adding custom properties to Array.prototype which is considered a bad practice (adding custom functions into Array.prototype).

Vue.js - How to pass parameters to a JavaScript filter function within a computed property?

I want to pass a variable as a parameter to a computed property.
computed: {
dishes() {
let param = this.cuisine;
let dishes = this.restaurant.restaurant_items.filter(element => {
element.param
});
return dishes;
}
},
data(){
return{
cuisine:""
}
}
Here as the param I pass a value which is an element of restaurant_items array's objects.
eg(:- is_thai)
But this doesn't output me anything. What's wrong with my code?
Computed properties don't accept parameters. But you can use a method to accomplish the same thing
methods: {
dishes(param) {
// return whatever
}
}
If I understand you correctly what you actually want to do is:
computed: {
dishes() {
return this.restaurant.restaurant_items.filter((e) => e[this.cuisine])
}
}
You need to use bracket notation to access object properties via a variable, not dot notation.

Access JS this from Scala.js

I'm trying to convert this code from js library docs into scala.s:
$('#myTable').on( 'click', 'tbody td', function () {
editor.inline( this, {
submitOnBlur: true
} );
} );
Code I tried:
$("#table").on("click", ".editable", (thiz: js.Dynamic) => {
editor.inline(thiz, JC(
submitOnBlur = true
))
})
But it gives me error:
Cannot read property 'contents' of undefined at f.inline
The callback function you wrote, i.e.,
(thiz: js.Dynamic) => {
editor.inline(thiz, JC(
submitOnBlur = true
))
}
is a function of 1 parameter (that happens to be called thiz), instead of a function that receives this as a parameter. In other words, it is equivalent to the following in JS:
function(thiz) {
editor.inline(thiz, JC(...))
}
To get access to the this, you need to force your callback function to be a js.ThisFunction, as follows:
((thiz: js.Dynamic) => {
editor.inline(thiz, JC(
submitOnBlur = true
))
}): js.ThisFunction
This will take the first argument of the Scala lambda (in this case, the only one) and attach it to the this value of JavaScript, which is what you want.

How to pass a parameter to a function that is passed to another function as string?

I have the following piece of code :
accountSelector.executeInParallel('processAccounts', 'postProcess');
function processAccounts() {
return JSON.stringify(syncMasterLists());
}
And instead of having this, I want to be able to pass a value to the processAccounts accounts function.
For the purpose I changed the code so it's looking like this now :
accountSelector.executeInParallel('processAccounts("DE")', 'postProcess');
function processAccounts(arg) {
return JSON.stringify(syncMasterLists());
}
Unfortunately, after introducing the change I started getting the following error :
Cannot find function processAccounts("DE").
I cannot understand am I doing this wrong(and if yes then what is wrong) or it's just something that can't be done.
I cannot understand am I doing this wrong(and if yes then what is
wrong) or it's just something that can't be done.
accountSelector.executeInParallel takes the function name as parameter and execute the same, processAccounts("DE") is not a valid function name or the name of the function that exists.
As per documentation, there is a way to pass optionalInput parameter
The input, if specified by optionalInput, will be passed into the
function specified by functionName
accountSelector.executeInParallel(functionName, optionalCallbackFunctionName, optionalInput)
In your case, it will be
accountSelector.executeInParallel('processAccounts', 'postProcess', 'DE' );
Why don't you call the function first and replace the result in the 'executeInParallel' method as follows:
var res = processAccounts("DE");
accountSelector.executeInParallel(res, 'postProcess');
function processAccounts(arg) {
return JSON.stringify(syncMasterLists());
}
Some closure can probably solve your problem, depends on how accountSelector.executeInParallel is implemented
const accountSelector = {
executeInParallel(pre, post) {
let result = eval(pre)()
eval(post)(result)
}
}
accountSelector.executeInParallel(processAccountsWithArg('Foo'), 'postProcess');
function processAccount(arg) {
console.log('processAccount', arg)
return JSON.stringify({
key: 'value'
});
}
function processAccountsWithArg(arg) {
return function() {
return processAccount(arg)
}
}
function postProcess(result) {
console.log('postProcess', result)
}

Why would you ever call .call() on Observable functions?

I am a relative beginner in Angular, and I am struggling to understand some source I am reading from the ng-bootstrap project. The source code can be found here.
I am very confused by the code in ngOnInit:
ngOnInit(): void {
const inputValues$ = _do.call(this._valueChanges, value => {
this._userInput = value;
if (this.editable) {
this._onChange(value);
}
});
const results$ = letProto.call(inputValues$, this.ngbTypeahead);
const processedResults$ = _do.call(results$, () => {
if (!this.editable) {
this._onChange(undefined);
}
});
const userInput$ = switchMap.call(this._resubscribeTypeahead, () => processedResults$);
this._subscription = this._subscribeToUserInput(userInput$);
}
What is the point of calling .call(...) on these Observable functions? What kind of behaviour is this trying to achieve? Is this a normal pattern?
I've done a lot of reading/watching about Observables (no pun intended) as part of my Angular education but I have never come across anything like this. Any explanation would be appreciated
My personal opinion is that they were using this for RxJS prior 5.5 which introduced lettable operators. The same style is used internally by Angular. For example: https://github.com/angular/angular/blob/master/packages/router/src/router_preloader.ts#L91.
The reason for this is that by default they would have to patch the Observable class with rxjs/add/operators/XXX. The disadvantage of this is that some 3rd party library is modifying a global object that might unexpectedly cause problems somewhere else in your app. See https://github.com/ReactiveX/rxjs/blob/master/doc/lettable-operators.md#why.
You can see at the beginning of the file that they import each operator separately https://github.com/ng-bootstrap/ng-bootstrap/blob/master/src/typeahead/typeahead.ts#L22-L25.
So by using .call() they can use any operator and still avoid patching the Observable class.
To understand it, first you can have a look at the predefined JavaScript function method "call":
var person = {
firstName:"John",
lastName: "Doe",
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
var myObject = {
firstName:"Mary",
lastName: "Doe",
}
person.fullName.call(myObject); // Will return "Mary Doe"
The reason of calling "call" is to invoke a function in object "person" and pass the context to it "myObject".
Similarly, the reason of this calling "call" below:
const inputValues$ = _do.call(this._valueChanges, value => {
this._userInput = value;
if (this.editable) {
this._onChange(value);
}
});
is providing the context "this._valueChanges", but also provide the function to be called base on that context, that is the second parameter, the anonymous function
value => {
this._userInput = value;
if (this.editable) {
this._onChange(value);
}
}
In the example that you're using:
this._valueChanges is the Input Event Observerable
The _do.call is for doing some side affects whenever the event input happens, then it returns a mirrored Observable of the source Observable (the event observable)
UPDATED
Example code: https://plnkr.co/edit/dJNRNI?p=preview
About the do calling:
You can call it on an Observable like this:
const source = Rx.Observable.of(1,2,3,4,5);
const example = source
.do(val => console.log(`BEFORE MAP: ${val}`))
.map(val => val + 10)
.do(val => console.log(`AFTER MAP: ${val}`));
const subscribe = example.subscribe(val => console.log(val));
In this case you don't have to pass the first parameter as the context "Observable".
But when you call it from its own place like you said, you need to pass the first parameter as the "Observable" that you want to call on. That's the different.
as #Fan Cheung mentioned, if you don't want to call it from its own place, you can do it like:
const inputValues$=this._valueChanges.do(value=>{
this._userInput = value;
if (this.editable) {
this._onChange(value);
}
})
I suppose
const inputValues$ = _do.call(this._valueChanges, value => {
this._userInput = value;
if (this.editable) {
this._onChange(value);
}
});
is equivalent to
const inputValues$=this._valueChanges.do(value=>{
this._userInput = value;
if (this.editable) {
this._onChange(value);
}
})
In my opinion it's not an usual pattern(I think it is the same pattern but written in different fashion) for working with observable. _do() in the code is being used as standalone function take a callback as argument and required to be binded to the scope of the source Observable
https://github.com/ReactiveX/rxjs/blob/master/src/operator/do.ts

Categories