what is the function 'bind'? [duplicate] - javascript

This question already has answers here:
What is the use of the JavaScript 'bind' method?
(23 answers)
Closed 4 years ago.
I have some question about function named bind.
I am testing some public source codes implemented in Angular.
I am trying to understand what the bind function, I searched internet but can't find proper answer. Could you give some guide for this?
export class AppComponent {
currentPage: number = 1;
news: Array<any> = [];
scrollCallback;
constructor(private hackerNewsSerivce: HackerNewsService) {
this.scrollCallback = this.getStories.bind(this);
}
getStories() {
return this.hackerNewsSerivce.getLatestStories(this.currentPage).do(this.processData);
}
private processData = (news) => {
this.currentPage++;
this.news = this.news.concat(news.json());
}
}

In terms of angular, function binding is used to declare a function in component/directive and define in the scope / this.
And we use where we need like volatile

Related

How to avoid duplicate JS code that each uses its own this? [duplicate]

This question already has answers here:
How to add mixins to ES6 javascript classes?
(4 answers)
Closed 9 months ago.
I have several different classes with the same duplicate code. Aside from the different identity of each's this, these duplicate code are all ostensibly identical.
Here's a simplified example:
class classA {
...
doSomething() {
if (!this.id || !this.data || !this.isAllowed()) {
return null;
}
return someImportedFunc(this.data, this.metadata, this.doSomethingElse());
}
}
class classB {
...
doSomething() {
if (!this.id || !this.data || !this.isAllowed()) {
return null;
}
return someImportedFunc(this.data, this.metadata, this.doSomethingElse());
}
}
// Many other classes like this
I've thought of moving the doSomething method to another class, then importing it in all these classes. But that would result in a very messy method that takes many, many arguments to account for all the different this's. It'd look like:
class exportedClass {
function doSomething(id, data, metadata, isAllowed, doSomethingElse) {
if (!id || !data || !isAllowed()) {
return null;
}
return someImportedFunc(data, metadata, doSomethingElse());
}
}
class classA {
...
methodThatUsesDoSomething() {
const result = exportedClass.doSomething(
this.id, this.data, this.metadata, this.isAllowed, this.doSomethingElse);
...
}
}
Except with like 15 args instead of 5 since this is a simplified example.
How can I avoid duplicate code in this kind of situation?
Assuming you want a non-inheritance solution, my suggestion would be to pass "this" as an argument, as prototypes can be manipulated as parameters. That would allow you to keep the parameters at a minimum while not losing data.

How do you (best) access 'this' in an object method passed as callback [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 4 years ago.
I'm writing a simple word game to practice my javascript (I'm new to it) using the NPM package prompt (https://www.npmjs.com/package/prompt) to query the user when I need a response.
Since I come from an OOP background (in other languages) I've been experimenting with encapsulating different functionalities in different objects. So I have all the prompt related code in one object, like this
function Prompter() {
this.getUserName = function (callback) {
var schema = {
properties: {
name: {
description: "Tu nombre por favor:",
pattern: /^[ñÑa-zA-Z\s\-]+$/,
message: 'Solo letras, por favor',
required: true
}
}
};
prompt.get(schema, callback);
};
}
and game logic in another object like this (this is the relevant part of the code)
function Game() {
this.qGenerator = null;
this.prompter = null;
this.user = "";
this.doNextRound = function () {
//// omitted for brevity
};
this.init = function () {
this.qGenerator = new QuestionGenerator();
this.prompter = new Prompter();
};
this.startGame = function () {
this.prompter.getUserName(this.storeUserName);
};
this.storeUserName = function (err, result) {
if (err) {
this.handleErr(err);
return;
}
this.user = result.name;
this.doNextRound();
};
}
and I start the game like this
const game = new Game();
game.init();
game.startGame();
The problem I have is that in the Game method storeUserName, which I've passed as a callback to prompt, I have no access to the Game object through this, and thus, when I call
this.doNextRound
inside of storeUserNameI get
TypeError: this.doNextRound is not a function
I understand why, as this refers to Node inside the callback. But I don't know how to keep a reference to the correct this inside the method I'm passing as callback. I understand how to do it in more 'vanilla' Javascript -- using that = this, or apply,etc, but I'm not sure what the best way to handle this inside Node callbacks is when you're passing another object's methods. Any advice much appreciated.
Use Function.prototype.bind:
this.prompter.getUserName(this.storeUserName.bind(this));
or an arrow function:
this.prompter.getUserName( _ => this.storeUserName() );
Either of those will work.

Arrays in angular 5 project is undefined but it is not [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
I have component in my angular 5 project, bill-page. On bill-page I get some info, bill and currency. It is two arrays, bill (array with one object, get it from my firebase) and currency (array with two objects, get it from free api). When I wanna chek this arrays by using
console.log()
it shows me that is two normal arrays with some objects.
export class BillPageComponent implements OnInit {
currency: any = [];
bill: any = [];
userId: string;
isLoaded = false;
copyCurrency: any = [];
constructor(private billService: BillService, private authService: AuthService) {}
ngOnInit() {
this.isLoaded = false;
this.userId = this.authService.returnAuthState();
this.billService.getBillFirebase(this.userId).subscribe(
(resp)=>{
for (let key in resp) {this.bill.push(resp[key])}
}
);
console.log(this.bill);//[{currency: "USD", value: 0}]
this.billService.getCurrencyPB().subscribe((data)=>{
this.currency.push(data[0]);
this.currency.push(data[1]);
});
console.log(this.currency); //[{key1:1, key2:2},{key3:3, key4:4}]
this.isLoaded = true;
}
But when I try get this objects from arrays, or property from objects it becomes undefined, for example
console.log(this.bill[0])// undefined or console.log(this.bill[0].value)//undefined
or if I try copy this arrays it becomes undefined too
this.copyCurrency = this.currency.slice();
console.log(this.copyCurrency) // undefined
Basically what happened was that it executed aysnchronously. console.log (this.bill) executed before it got any value. this.bill gets the value only inside the subscribe function.

How to update a variable inside forEach function? Getting Cannot read property of undefined [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 4 years ago.
export class myclass implements OnInit {
private outagesList;
private outageArray;
constructor(private outages: OutagesService){}
ngOnInit(){
this.outages.getOutagesList().subscribe((data) => {
this.outagesList = data;
this.outagesList.forEach( function (arrayItem)
{
this.outageArray.push(arrayItem["title"]);
});
)
}
If i try to push the data into outageArray it is throwing ERROR TypeError: Cannot read property 'outageArray' of undefined
How can i avoid this error? I need to access this outageArray value to html.
Use an arrow function
this.outagesList.forEach((arrayItem) => {
this.outageArray.push(arrayItem["title"]);
});
Once you are using post-ES6 Javascript, functions like forEach are not likely to be your best solution. The easiest way to do this is with a for..of loop:
this.outages.getOutagesList().subscribe((data) => {
this.outagesList = data;
for (let arrayItem of this.outagesList)
{
this.outageArray.push(arrayItem.title);
});
)

How to update Array In Vue.js using method? [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 5 years ago.
I Can't Update my array using methods in Vue.js !
<script>
import Vue from 'vue';
export default {
data () {
return {
from:'',
to:'',
places:[]
}
},
methods:{
searchFrom:function(){
var autoComplete = new google.maps.places.AutocompleteService();
autoComplete.getPlacePredictions({input:this.from},function(data){
this.places=data;
});
}
},
computed:{
}
}
</script>
<style>
</style>
This throws an error on console: "Uncaught TypeError: Cannot read property 'places' of undefined"
This is because you're not using fat arrows, change the code to:
methods:{
searchFrom (){
var autoComplete = new google.maps.places.AutocompleteService();
autoComplete.getPlacePredictions({input:this.from}, data => {
this.places=data;
});
}
},
In more details:
when you call autoComplete.getPlacePredictions it uses a callback, and in that callback the this context is changed and is no longer Vue context, so it does not know what this.places is. Fat arrow (=>) takes care of it and makes sure that the context remains the same.
I've never had good luck using fat arrows in Vue. The this is not what you expect. Try explicitly assigning this at the start of your searchFrom() method, like this...
methods:{
searchFrom (){
var me = this;
var autoComplete = new google.maps.places.AutocompleteService();
autoComplete.getPlacePredictions({me.from}, data => {
me.places=data;
});
}
}

Categories