Метеор: ошибка: {{#each}} в настоящее время принимает только массивы, курсоры или ложные значения

Я продолжаю получать это сообщение об ошибке, когда нажимаю кнопку отправки. Я пытаюсь создать приложение для обмена мгновенными сообщениями, в котором онлайн-пользователи могут общаться один на один. Я новичок, и я был бы очень признателен за любую помощь. Вот мое сообщение об ошибке, оно снова появляется в консоли, когда я нажимаю кнопку «Отправить».

Исключение из функции пересчета Tracker: meteor.js:862 Ошибка: {{#each}} в настоящее время принимает только массивы, курсоры или ложные значения. в badSequenceError (observe-sequence.js:148) в наблюдать-sequence.js:113 в Object.Tracker.nonreactive (tracker.js:597) в наблюдать-sequence.js:90 в Tracker.Computation._compute (tracker.js :331) в Tracker.Computation._recompute (tracker.js:350) в Object.Tracker._runFlush (tracker.js:489) в onGlobalMessage (meteor.js:347)

Вот мой HTML

<template name="chat_page">
  <h2>Type in the box below to send a message!</h2>
  <div class="row">
    <div class="col-md-12">
      <div class="well well-lg">
        {{#each messages}}
          {{> chat_message}}
        {{/each}}
      </div>  
    </div>
  </div>
  <div class="row">
    <div class="col-md-12">
      <form class="js-send-chat">
        <input class="input" type="text" name="chat" placeholder="type a message here...">
        <input type="submit" value="Send">
      </form>
    </div>
  </div>
</template>

<!-- simple template that displays a message -->
<template name="chat_message">
  <div class = "container">
    <div class = "row">
      <img src="/{{profile.avatar}}" class="avatar_img">
      {{username}} said: {{text}}
    </div>
  </div>  
  <br>
</template>

Сторона клиента

Template.chat_page.helpers({
  messages: function () {
    var chat = Chats.findOne({ _id: Session.get("chatId") });
    return chat.messages;
  }, 
  other_user: function () {
    return "";
  }
});

Template.chat_page.events({
  'submit .js-send-chat': function (event) {
    console.log(event);
    event.preventDefault();
    var chat = Chats.findOne({ _id: Session.get("chatId") });
    if (chat) {
      var msgs = chat.messages; 
      if (! msgs) {
        msgs = [];
      }
      msgs.push({ text: event.target.chat.value });
      event.target.chat.value = "";
      chat.messages = msgs;
      Chats.update({ _id: chat._id }, { $set : { messages: chat } }); 
      Meteor.call("sendMessage", chat);
    }
  }
});

Части серверной части

Meteor.publish("chats", function () { 
  return Chats.find(); 
});

Meteor.publish("userStatus", function () {
  return Meteor.users.find({ "status.online": true });
});

Meteor.publish("userData", function () {
  if (this.userId) {
    return Meteor.users.find({ _id: this.userId },{ fields: { 'other': 1, 'things': 1 } });
  } else {
    this.ready();
  }
  return Meteor.users.find({ "status.online": true });
});

Meteor.publish("users", function () {
  return Meteor.users.find({ "status.online": true });
});

Chats.allow({
  insert: function () { return true; },
  update: function () { return true; },
  remove: function () { return true; }
});

Meteor.methods({
  sendMessage: function (chat) {
    Chats.insert({
      chat: chat,
      createdAt: new Date(),
      username: Meteor.user().profile.username,
      avatar: Meteor.user().profile.avatar,
    });
  }
});

person Jessica    schedule 12.02.2016    source источник
comment
Какой тип значения хранится в поле messages?   -  person umesh    schedule 12.02.2016
comment
В частности, является ли тип массивом или ложным значением? Как говорит ошибка, блок {{#each}} принимает только массивы, курсоры или ложные значения. Поскольку messages — это поле в документе чата, вы сможете использовать {{#each}} в сообщениях, если его значение является либо массивом, либо ложным значением.   -  person umesh    schedule 12.02.2016
comment
хм, я понимаю, что вы говорите. Сообщения должны отображать каждое сообщение, отправленное пользователем (chat_message). Насколько я понимаю, сообщения должны отображать каждое сообщение chat_message в виде массива. Может ли ошибка в шаблоне chat_message привести к неправильной вставке? В результате #each не читается правильно.   -  person Jessica    schedule 12.02.2016
comment
Я не думаю, что ошибка в шаблоне chat_message приведет к ошибке, о которой вы сообщили. Ошибка конкретно в строке {{#each messages}}, так как она не получает действительного значения.   -  person umesh    schedule 12.02.2016


Ответы (2)


Скорее всего, ваши подписки не готовы. Это означает, что Chats.findOne() ничего не вернет, а Chats.findOne().messages будет неопределенным.

Попробуйте следующее:

{{ #if Template.subscriptionsReady }}
  {{#each messages}}
  {{/each}}
{{/else}}

В качестве альтернативы используйте find() для чатов, а затем {{#each}} для сообщений в этом чате. Например:

Template['Chat'].helpers({
  chats: function () {
    return Chats.find(Session.get('chatId')); // _id is unique, so this should only ever have one result.
  }
});

Затем в шаблоне:

{{#each chats}}
  {{#each messages}}
    {{>chat_message}}
  {{/each}}
{{/each}}
person corvid    schedule 12.02.2016
comment
Если подписки не готовы, не будет ли Chats.findOne() неопределенным, а доступ к Chats.findOne().messages приведет к ошибке Cannot read property 'messages' of undefined вместо ошибки, о которой сообщил OP? - person umesh; 12.02.2016
comment
Кроме того, даже если Chats.findOne().messages не определено, это все равно не объясняет ошибку, поскольку undefined, являющееся ложным значением, является допустимым значением в отношении блока {{#each}}. - person umesh; 12.02.2016

Я думаю, что в этой строке может быть логическая ошибка

Chats.update({ _id : chat._id }, { $set : { messages : chat } });

Вы устанавливаете значение поля messages в chat. Но chat — это объект. Таким образом, в вашем помощнике, когда вы возвращаете Chats.findOne().messages в блок {{#each}}, вы фактически возвращаете объект, который не является допустимым значением для отправки в блок {{#each}} и, следовательно, ошибку.

Я думаю, что вы хотите сделать это

Chats.update({ _id : chat._id }, { $set : { messages : msgs } });
person umesh    schedule 12.02.2016
comment
Большое спасибо. Это сработало, поскольку удалило ошибку, но мои сообщения все еще не появляются, но когда я перехожу к главному, я получаю еще одну ошибку, и я считаю, что это то, что мешает появлению сообщений. - person Jessica; 12.02.2016
comment
Исключение в помощнике по шаблону: TypeError: не удается прочитать «сообщения» свойства неопределенного - person Jessica; 12.02.2016
comment
Я понимаю. В помощнике messages попробуйте заменить строку return chat.messages; на return chat && chat.messages;. - person umesh; 12.02.2016
comment
Окончательно помог с ошибкой, спасибо. У меня все еще есть проблемы с появлением фактических сообщений. Как только я нажимаю отправить, ничего не появляется. Ошибок нет, но и ничего не появляется. Я хочу, чтобы вы знали, что я очень благодарна вам за вашу помощь. - person Jessica; 12.02.2016
comment
Просто хотел, чтобы вы знали, что я понял это. Я забыл опубликовать и подписаться на сообщения. Еще раз спасибо за вашу помощь!! - person Jessica; 12.02.2016
comment
Большой. Рад быть полезным (по крайней мере, с вашей первоначальной проблемой). Вы можете принять ответ, если он вам помог, так как другие программисты, ищущие этот вопрос, могут найти его полезным. - person umesh; 14.02.2016