0

When i try:

    this.rezerwacjeFilteredByseaarchInput.sort(function (a, b) {
      if (this.idSortOrder) {
        return a[0].id - b[0].id;
      }
      else {
        return b[0].id - a[0].id;
      }

    });

js throws: this.idSortOrder is undefined. but when i try:

let idSortOrder = this.idSortOrder;
    this.rezerwacjeFilteredByseaarchInput.sort(function (a, b) {
      if (idSortOrder) {
        return a[0].id - b[0].id;
      }
      else {
        return b[0].id - a[0].id;
      }

    });

it works. can anybody show me how to this.idSortOrder directly in sort or foreach function?

Pawel
  • 147
  • 1
  • 1
  • 12
  • Use an arrow function or pass this via the this parameter of forEach (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach). I’d also familiarize yourself with this, Kyle Simpson’s free book explains this well (https://github.com/getify/You-Dont-Know-JS). Also lookup closures and specifically lexical scoping (JS definitive 6th ed. is good!). – prasanthv Jan 18 '18 at 08:17

4 Answers4

2

This problem arises because this, in the callback, isn't the one you expect (it's undefined in strict mode, the global object in loose mode). You can use an arrow function to preserve it.

Replace

this.rezerwacjeFilteredByseaarchInput.sort(function (a, b) {

with

this.rezerwacjeFilteredByseaarchInput.sort((a, b) => {

Or if you need to be compatible with old browsers and can't use transpilers like Babel, simply store this:

var nameThatObject = this;
this.rezerwacjeFilteredByseaarchInput.sort(function (a, b) {
      if (nameThatObject.idSortOrder) {
Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • 1
    OP should also look at [bind, call and apply functions](https://stackoverflow.com/questions/15455009/javascript-call-apply-vs-bind) to change the value of `this` inside functions. – xander Jan 18 '18 at 08:00
  • 1
    ^.. + `forEach` has its own parameter for the `this` value. – Teemu Jan 18 '18 at 08:01
1

You can also use .bind:

this.rezerwacjeFilteredByseaarchInput.sort(function (a, b) {
  if (this.idSortOrder) {
    return a[0].id - b[0].id;
  }
  else {
    return b[0].id - a[0].id;
  }

}.bind(this));

This will bind the context your inner closer to be that of the outer one.

Kousha
  • 32,871
  • 51
  • 172
  • 296
1

"this" inside the function doesn't point to the same object as that of "this" present outside the function,that is the reason we aren't able to access "idSortOrder" property Look at this description ,instead try this:

var self = this;
this.rezerwacjeFilteredByseaarchInput.sort(function (a, b) {
  if (self .[enter link description here][1]idSortOrder) {
    return a[0].id - b[0].id;
  }
  else {
    return b[0].id - a[0].id;
  }
});
1

I like @answered’s response but for wider support forEach does provide the option to pass a this parameter. So would recommend that for that scenario instead.

arr.forEach(function callback(currentValue[, index[, array]]) {
    //your iterator
}[, thisArg]);

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

prasanthv
  • 2,442
  • 2
  • 21
  • 17