Метеор: & ldquo; TypeError: undefined не является объектом & rdquo; при использовании коллекции

Вот версия ES6, использующая reduce

perChunk = 2 // items per chunk    

inputArray = ['a','b','c','d','e']

inputArray.reduce((resultArray, item, index) => { 
  const chunkIndex = Math.floor(index/perChunk)

  if(!resultArray[chunkIndex]) {
    resultArray[chunkIndex] = [] // start a new chunk
  }

  resultArray[chunkIndex].push(item)

  return resultArray
}, [])

// result: [['a','b'], ['c','d'], ['e']]

. И вы готовы цеплять дальнейшие преобразования карты / уменьшения. Ваш входной массив остается неповрежденным


Если вы предпочитаете более короткую, но менее читаемую версию, вы можете посыпать некоторые concat в микс для того же конечного результата:

inputArray.reduce((all,one,i) => {
   const ch = Math.floor(i/perChunk); 
   all[ch] = [].concat((all[ch]||[]),one); 
   return all
}, [])
1
задан LuMa 5 March 2019 в 23:28
поделиться

1 ответ

Это связано с тем, как работает Метеор.

Когда клиент запускается, у него еще нет данных. Затем клиент открывает подписки на сервере (при условии, что у вас все еще установлен пакет автоматической публикации по умолчанию, это сделано для вас), который вскоре отправляет данные.

Именно эта «вскоре после» часть является проблемой здесь.

В вашем случае это означает, что когда Tweets.findOne() выполняется, у него еще нет данных, и поэтому нет документа для чтения text. Таким образом, ошибка. Предотвратите ошибку, проверив, был ли возвращен документ:

Template.tweet.onCreated(function () {
  var doc = Tweets.findOne();
  if (doc) {
    this.text = new ReactiveVar(doc.text);
  }
});

Если вы попробуете это, ошибка исчезнет, ​​но текст по-прежнему не будет отображаться.

Итак, теперь мы хотим, чтобы этот участок кода запускался снова, когда доступны данные. Blaze делает это автоматически в помощниках, но везде вам нужно обернуть его в autorun:

Template.tweet.onCreated(function () {
  this.text = new ReactiveVar();
  this.autorun(() => {
    var doc = Tweets.findOne();
    if (doc) {
      this.text.set(doc.text);
    }
  });
});

Я также переместил создание реактивной переменной из автозапуска, потому что мы хотим создать ее только один раз, а затем установите или получите его значение.

В качестве альтернативы, я упоминал ранее, что помощники автоматически запускаются. Это означает, что вы можете найти твит в помощнике, чтобы немного упростить ваш шаблон:

Template.tweet.helpers({
  text() {
    var doc = Tweets.findOne();
    if (doc) return doc.text;
  },
});

Более того, нам больше не нужен ReactiveVar и мы можем удалить всю функцию onCreated! [ 1116]

0
ответ дан Fred Stark 5 March 2019 в 23:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: