Неясна причина появления ошибки TypeError: Cannot read property 'XXX' of undefined [дубликат]

107
15 ноября 2020, 22:40
На этот вопрос уже даны ответы здесь:
Потеря контекста вызова (5 ответов)
Почему появляется ошибка undefined? (2 ответа)
Закрыт 1 год назад.

Перечитал много раз ответы на вопрос Почему появляется ошибка undefined?

Но так и не нашел для себя отгадку

Я только изучаю язык, помогите, пожалуйста, разобраться

Есть тест:

describe('Wait Test', () => {
  it('should wait for true "false"', () => {
    const wait = new Wait()
    return wait.forTrue(() => false, 5, 1000, 0).then((result) => assert.isFalse(result))
  })

В нем вызываются методы и функции класса Wait:

const logger = require('./log.util')
const doWait = (action, interval, expectedValue) => {
  return new Promise((resolve, reject) => {
    if (action() === expectedValue) {
      setTimeout(() => resolve(), interval)
    } else {
      setTimeout(() => reject(() => {
        return action()
      }), interval)
    }
  })
}
const retrier = async (action, maxCount, interval, count, forFunction, expectedValue) => {
  count++
  logger.info(`[${count}] Wait for true`)
  return doWait(action, interval, expectedValue).then(() => {
    logger.info('Was able to reach expected condition!')
    return true
  }, () => {
    if (maxCount <= count) {
      logger.warning('Was not able to reach expected condition!')
      logger.warning(`[${text}] -> last data from action(): ` + action())
      return false
    } else {
      return forFunction(action, maxCount, interval, count)
    }
  })
}
class Wait {
  forTrue (action, maxCount, interval, count = 0) {
    return retrier(action, maxCount, interval, count, this.forTrue, true)
 };
}

И получается в итоге (в строке return retrier(action, maxCount, interval, count, this.forTrue, true)) такая ошибка

  1) Wait Test
       should wait for true "false":
     TypeError: Cannot read property 'forTrue' of undefined
      at forTrue (utils/wait.util.js:34:60)
      at doWait.then (utils/wait.util.js:27:14)

Не могли бы подсказать, что не так и объяснить поему надо именно так

спасибо

Answer 1
class Wait {
  forTrue (

у вас сделаны, как класс и метод. В метод автоматически не передается контекст this. Надо сделать либо:

class Wait {
  constructor() {
      this.forTrue = this.forTrue.bind(this);
  }
  forTrue (....) {
      ....
  }
}

либо сделать метод стрелочной функцией:

class Wait {
  forTrue = (....) => {
      ....
  };
}
Answer 2
class Wait {
  forTrue (action, maxCount, interval, count = 0) {
    return retrier(action, maxCount, interval, count, this.forTrue.bind(this), true)
 };
}
READ ALSO
Как работают stage и Scene в telegraf.js?

Как работают stage и Scene в telegraf.js?

Подскажите пожалуйста
Что я хочу сделать, следующий сценарий

361
Преобразование массив в дерево js

Преобразование массив в дерево js

Есть массив данных, который необходимо преобразовать в дерево:

129
Bitfinex API websocket

Bitfinex API websocket

Пытаюсь вывести орред бук через вебсокеты битфинекса, но в консоли получаю ошибку

153
Скрытие элементов списка

Скрытие элементов списка

Подскажите пожалуйста как реализовать такую возможность: Чтобы когда нажималась кнопка Войти в комнату, уже открытая комната закрывалась?...

148