find
O método retorna um cursor, não um objeto nem um array. Para acessar o objeto, você precisa buscá-lo no cursor var skill = Skills.find(Session.get('selected_skill')).fetch()[0];
ou obtenha-o diretamente com
findOne
:var skill = Skills.findOne(Session.get('selected_skill'));
Então você pode usá-lo como qualquer outro objeto js:
console.log(skill.mana);
skill._cache = {cooldown: true};
Lembre-se de que, no lado do cliente, métodos de coleta como
find
são não bloqueantes. Eles retornam o que o Meteor tem em cache, não necessariamente o que está no banco de dados do lado do servidor. É por isso que você deve sempre usá-los em um contexto reativo, ou garantir que todos os dados tenham sido buscados antes da execução (não se preocupe com o último até que você seja fluente com o Meteor, comece com o primeiro caminho). Além disso, você precisa ter em mente que, por causa disso,
findOne
e find.fetch
pode retornar null
/ array vazio, mesmo quando o elemento correspondente está em db (mas ainda não foi armazenado em cache). Se você não levar isso em consideração em suas funções reativas, você encontrará erros. Template.article.slug = function() {
var article = Articles.findOne(current_article);
if(!article) return '';
return slugify(article.title);
};
Se não escaparmos da função com
if(!article)
, a expressão article.title
geraria um erro no primeiro cálculo, pois article
seria indefinido (assumindo que não foi armazenado em cache anteriormente). Quando você deseja atualizar o banco de dados do lado do cliente, você pode alterar apenas um item por vez e deve se referir ao item por seu
_id
. Isto é devido a razões de segurança. Sua linha para isso estava ok:Skills.update(Session.get('selected_skill'), {$inc: {mana: 1}});
alert()
é uma função que retorna indefinido, não importa o que você alimente. alert(42); // -> undefined
Geralmente, é longe melhor depurar com
console.log
do que com alert
.