Причина:
Причина, по которой это undefined
, заключается в том, что вы выполняете асинхронную операцию. Это означает, что потребуется некоторое время, чтобы закончить метод getEventList
(в зависимости от скорости вашей сети).
Итак, посмотрим на http-вызов.
this.es.getEventList()
После вас на самом деле сделать («пожар») ваш запрос http с subscribe
, вы будете ждать ответа. Во время ожидания javascript выполнит строки под этим кодом, и если он встретит синхронные назначения / операции, он немедленно их выполнит.
Итак, после подписки на getEventList()
и ожидания ответа,
console.log(this.myEvents);
строка будет выполнена немедленно. И значение этого параметра - undefined
до того, как ответ поступит с сервера (или во все, что вы его инициализировали в первую очередь).
Это похоже на выполнение:
ngOnInit(){
setTimeout(()=>{
this.myEvents = response;
}, 5000);
console.log(this.myEvents); //This prints undefined!
}
Решение:
Итак, как мы можем преодолеть эту проблему? Мы будем использовать функцию обратного вызова, которая является методом
blockquote>subscribe
. Потому что, когда данные поступают с сервера, они будут внутриsubscribe
с ответом.Поэтому изменение кода на:
this.es.getEventList() .subscribe((response)=>{ this.myEvents = response; console.log(this.myEvents); //<-- not undefined anymore });
будет печатать ответ .. через некоторое время. Что вы должны делать:
В вашем ответе может быть много чего другого, кроме как его регистрация; вы должны делать все эти операции внутри обратного вызова (внутри функции
subscribe
), когда данные поступают.Еще одна вещь, которая стоит упомянуть, состоит в том, что если вы исходите из фона
Promise
,then
обратный вызов соответствуетsubscribe
с наблюдаемыми. Что вам не следует делать:Не следует пытаться изменить операцию async на операцию синхронизации (но не на то, что вы можете). Одной из причин, по которым мы имеем асинхронные операции, является то, что пользователь не должен ждать завершения операции, пока они могут делать другие вещи за этот период времени. Предположим, что одна из ваших операций async длится 3 минуты, если у нас не было асинхронных операций, интерфейс застыл в течение 3 минут.
Рекомендуемое чтение:
Оригинальный кредит на этот ответ: Как вернуть ответ от асинхронного вызова?
Но с выпуском angular2 мы были введены для машинописных и наблюдаемых данных, поэтому этот ответ можно надеяться охватывает основы обработки асинхронного запроса с помощью наблюдаемых.
Справа от Метеорная документация :
Meteor.publish("userData", function () {
return Meteor.users.find({_id: this.userId},
{fields: {'other': 1, 'things': 1}});
});
А также:
Meteor.publish("allUserData", function () {
return Meteor.users.find({}, {fields: {'nested.things': 1}});
});
Надеюсь, это поможет.
Как упоминалось выше, функции публикации
Meteor.publish("userData", function () {
return Meteor.users.find({_id: this.userId},
{fields: {'other': 1, 'things': 1}});
});
и
Meteor.publish("allUserData", function () {
return Meteor.users.find({}, {fields: {'nested.things': 1}});
});
будут вытеснять данные из коллекции Users.
Подписать с
Tracker.autorun(function () {
Meteor.subscribe("userData");
Meteor.subscribe("allUserData");
});
И дополнительные данные автоматически войдут в коллекцию Users и будут доступны в объекте Meteor.user()
.
autosubscribe
один бит. Это устарело?
– Jonathan Dumaine
14 October 2013 в 09:48
Моя история с этим: я продолжил, как говорит документация, но столкнулся с странным поведением. У меня была функция публикации, где я опубликовал весь профиль и объект электронной почты для текущего пользователя (скажем, userData
) и просто некоторое подмножество для других пользователей (allUserData
).
Когда у меня было -
Meteor.subscribe("allUserData");
Meteor.subscribe("userData");
На стороне клиента сразу после входа пользователя я получил только данные allUserData
. Это означает даже для моего зарегистрированного пользователя (этот пользователь не мог видеть свой собственный адрес электронной почты). Когда я обновляю браузер, ошибка была исправлена, и я получил allUserData
для всех пользователей, кроме одного входа в систему, у которого есть свой userData
(с указанным адресом электронной почты).
Что интересно, если я изменил последовательность этих подписчиков, исправлена ошибка .:
Meteor.subscribe("userData");
Meteor.subscribe("allUserData");
Ввод в Meteor.autosubscribe(function () { })
ничего не изменил. Наконец, я попытался включить эту подписку в Deps.autorun(function() { })
и явно добавить реактивность, и проблема с последовательностью была решена ..:
Deps.autorun(function() {
Meteor.subscribe("allUserData", Meteor.userId());
Meteor.subscribe("userData", Meteor.userId());
// or
// Meteor.subscribe("userData", Meteor.userId());
// Meteor.subscribe("allUserData", Meteor.userId());
});
В функции публикации я просто заменяю this.userId
на userId
из параметра.
Со следующей ошибкой, с которой я столкнулся, был тот, что у меня есть секретный объект systemData в объекте пользователя профиля, который может видеть только администраторов, а не регулярно регистрироваться в пользователях. Но хотя правильный набор функции публикации с 'profile.systemData': 0
, этот секретный объект мог видеть всех зарегистрированных пользователей, которые рассматривали его объект профиля. Вероятно, это потому, что мои функции публикации каким-то образом мешали функции публикации в пакете Meteor Account:
// Publish the current user's record to the client.
Meteor.publish(null, function() {
if (this.userId) {
return Meteor.users.find(
{_id: this.userId},
{fields: {profile: 1, username: 1, emails: 1}});
} else {
return null;
}
}, /*suppress autopublish warning*/{is_auto: true});
В любом случае я разрешил ее с помощью метода Account.onCreateUser()
и добавил systemData рядом с объектом профиля, а не в профиль. Там начинаются мои другие проблемы :) см. Обратный вызов Meteor.loginWithPassword не предоставляет пользовательский объект в учетных записях пользователей doc
PS: Если бы я знал это с самого начала, я поставил systemData объект в специальную коллекцию.
subscribe
былuserData
, но мне тяжело. Может быть, потому, что у меня нет четкого понимания концепции метеор. Как мне установить его на стороне клиента? – user482594 10 November 2012 в 10:02