Why arrow function is not passing arguments?

2019-09-16 08:56发布

问题:

I'm using angular w/ rxjs to observe user events on the interface. However, I'm having this really simple problem with passing arguments to a method in an arrow function. Here is the problem:

This is not working: searchterm is not being passed to this.searchFacilities

ngOnInit() {
 this.searchTerm$.subscribe(searchterm => this.searchFacilities);/**Not working here**/
}

searchFacilities(term: string){
  console.log(term);
  this.facilityservice.searchFacilities(term)
    .subscribe(results => this.facilityList = results);
}

But this works:

this.searchTerm$.subscribe(searchterm => { this.searchFacilities(searchterm); })

Clearly, I have other solutions that are pretty painless, but I really want to understand why my first approach is not working. Thanks!

回答1:

Small clarification. The doc says you need to pass a callback to subscribe() and that this callback will receive the value(s) emitted by the observable.

We could write it like this:

const myCallBack = (val) => console.log(val);
Observable.range(0, 3).subscribe(myCallBack);

In your case you already have a callback, this.searchFacilities.
This means you can simply write:

this.searchTerm$.subscribe(this.searchFacilities);

Just like you can rewrite my original example to:

// Now `console.log` is the callback!
Observable.range(0, 3).subscribe(console.log);

In other words, the problem is not "Why arrow function is not passing arguments". The problem is that you created an arrow function whose body IS your callback, instead of just using your callback directly.

The expanded version of your code would look like this:

const myCallBack = (searchterm) => {
  return this.searchFacilities;
}

As you can see, searchFacilities is neither invoked nor does it receive the searchterm param.

You could have run into the same problem with a NON-ARROW function by writing the following code (although the syntax of arrow functions does make the mistake more likely and insidious):

const myCallBack = function(searchterm) {
  return this.searchFacilities;
}


回答2:

Because the parameter is not passed directly to your function.

Example from the doc:

Rx.Observable.range(0, 3).subscribe(function (x) { console.log(x) });

The same example with an arrow function:

Rx.Observable.range(0, 3).subscribe(x => console.log(x));


回答3:

Because you're getting a reference to the searchTerm but you're not doing anything with it. You could just do this.searchTerm$.subscribe(this.searchFacilities) and the term will be passed into the function.



回答4:

You searchFacilities function is declared in global scope, and then is called inside of ngOnInit as a callback and its context is not anymore global scope, now this points to ngOnInit element Object. In order to work inside ngOnInit object you need to bind it and then searchFacilities be method of ngOnInit and in this way its going to work.