Meteor not outputting MongoDB query - javascript

main.html:
{{#each getRequests}}
<li>{{_id}}</li>
{{/each}}
main.js
if (Meteor.isClient) {
Meteor.subscribe('getRequests',{fbID : Meteor.user().services.facebook.id});
}
publications.js
Meteor.publish('getRequests', function(args) {
return data.find({"potentialUsers.user_id" : args.fbID});
});
I'm stuck trying to get the main.html to display the IDs from the database. The user's ID can be in multiple documents in the "data" table, nested within data.potentialUsers.user_id. What I don't understand is that when I put the query into meteor mongo (in the command line) it executes successfully.

I am fairly new to meteor myself, but reading through the docs I see these issues.
Subscribe makes the documents available to the client from the publication. You still need to write a function to deliver them to the html.
main.js
if (Meteor.isClient) {
Meteor.subscribe('getRequests',{fbID : Meteor.user().services.facebook.id});
Template.body.helpers({
getRequests: function(){
return data.find() // since you want everything the publication has.
}
})
}
Then in your html:
{{#each getRequests}}
<li>{{_id}}</li>
{{/each}}

Related

Meteor - Not updating in real time anymore

Just started using Meteor and am loving it thus far.
I'm making a variation of the tutorial "todo" app, but with my own customization.
More or less the changes I made so far have been:
Changed directory structure to client, server, public, lib/collections folders
Made the task collection through collection2 schema rather than dynamically creating with Tasks.insert(title = text,etc etc)
So to the question.
These are my client/server files -
server.js
Meteor.publish("tasks", function () {
return Tasks.find({}, {sort: {checked: 1}});
});
client.js
// This code only runs on the client
Meteor.subscribe("tasks");
Template.task.events({
"click .toggledone": function () {
// Set the checked property to the opposite of its current value
Tasks.update(this._id, {
$set: {checked: ! this.checked}
});
},
"click .delete": function () {
Tasks.remove(this._id);
}
});
And its being displayed in the standard html
<ul>
{{#each tasks}}
{{> task}}
{{/each}}
</ul>
So basically as it is now, my server is sorting the tasks on the basis of whether it is checked (completed) or not, ascending.
It works currently, when I click a task on the list, it turns red (my configuration) and registers as completed, but the list doesn't sort automatically like it did originally (before I made the directory changes).
For it to update, I need to refresh the page which is not what I want.
I'm new to this and i think it has something to do with my publish/subscribe but I can't seem to find anything to help me online.
Can anyone point me in the right direction for this?
Thanks so much.
I think you are confused between the publication/subscription named tasks and the collection tasks for the loop on the template. When you want to render the tasks on the template, it should be returned from a helper. Consider that publication/subscription making the correct part of the database available on the client and then, you retrieve the correct data from that part to display.
Normally, I make the naming convention for the publication like the SQL query so it is easier to interpret
Meteor.publish("select-from-tasks", function () {
return Tasks.find({});
});
and then,
Meteor.subscribe("select-from-tasks");
You will need to have a helper to return the correct data, like I said above
Template.task.helpers({
tasks: function() {return Tasks.find({}, {sort: {checked: 1}});}
});

MongoDB data not appearing in Meteor template

I started my first app with Meteor and everything was going fine, until I noticed that a collection is no longer showing in a template.
This is my code:
App.js
Tasks = new Mongo.Collection("tasks");
if (Meteor.isServer) {
Meteor.publish("tasks", function () {
return Tasks.find();
});
}
if (Meteor.isClient) {
Meteor.subscribe("tasks");
Template.body.helpers({
tasks: function () {
return Tasks.find({}, {sort: {createdAt: -1}});
}
});
}
App.html
<template name="home">
<h3>Open Tasks</h3>
<ul>
{{#each tasks}}
{{> displayTasks}}
{{/each}}
</ul>
</template>
<template name="displayTasks">
<li>{{text}}</li>
</template>
Routes.js
Router.route("/", function () {
this.render("Home");
});
I've double-checked with http://meteortips.com/second-meteor-tutorial/publish-subscribe/ and MeteorJS template not showing data, not appearing and it seems that I've done everything correctly. I also tried changing the names and trying to display the tasks on different templates, but to no avail. MongoDB does have data and I can manually insert entries (using the Mongo console) that have their text fields filled out.
What else can I do to troubleshoot? Backtracing my steps hasn't helped and I'd rather avoid starting a new app from scratch.
NOTE: I'm using Iron Router.
By default, child templates don't have access to their parent's helpers. In the code above, the tasks helper has been defined for the body template, but it's needed in the home template. Try this instead:
Template.home.helpers({
tasks: function () {
return Tasks.find({}, {sort: {createdAt: -1}});
}
});
Note that you can explicitly pass a helper from a parent to a child, as seen in my answer to this question, but that's uncommon.

Why is the template not updating in real time?

I have this Meteor code which is meant to update a notifications' template in real time whenever an appropriate action is triggered:
~/server/app.js
Meteor.methods({
notifs: function(){
return Meteor.users.findOne({_id:this.userId}, {'profile.notifs': 1});
}
});
and:
~/client/apps.js
Template.notifs.helpers({
notifs: function(){
Meteor.call('notifs', function(err, data){
Session.set('notifs', data);
});
return Session.get('notifs');
}
});
finally:
~/public/templates/notifs.html
<template name='notifs'>
{{#each notifs}}
<p>...</p>
{{/each}}
</template>
What this code does for the moment is just listing the notifications when the user logs in, but fails to update in real time to show new notifications as actions are triggered.
New notifications show up only after a page refresh (which is, honestly, useless).
After hours of googling I give up and post this here so someone can help me, please.
Thanks in advance.
At it's core, this question is about reactivity. Because Meteor.call isn't a reactive data source (it's just a remote procedure call), the helper won't run again if the underlying data changes.
Because the necessary user document is already published (it's for the current user), the method call isn't needed. You could rewrite your helper using find (a reactive data source) like this:
Template.notifs.helpers({
notifs: function() {
return Meteor.users.findOne({_id: Meteor.userId()});
}
});
However, Meteor.user() gives you the same functionality:
Template.notifs.helpers({
notifs: function() {
return Meteor.user();
}
});
However, you don't really even need this because templates come with the {{currentUser}} helper. So you can drop the helper altogether and modify your template like this:
<template name='notifs'>
{{#each currentUser.notifs}}
<p>...</p>
{{/each}}
</template>
If you ever actually do need the result of a meteor call in a helper, you should read the answers to this question.

How to get a single record to the template from model in emberjs

I'm new to ember js. I was trying to get a single record from my mongo db database but the query to server returns the full list view instead of a record.
templates/profile.hbs
{{#each item in model}}
{{item.userName}}
{{/each}}
routes/profile.hbs
export default Ember.Route.extend({
model: function() {
return this.store.find('user',{userName:'sanka'});
}
});
New syntax for printing arrays is:
{{#each model as |item|}}
{{item.userName}}
{{/each}}
Does your backend have a support for this kind of filter? Go check your network tab. Otherwise we won't be able to tell what your issue is. But it really looks as if you dont have support in your mongoDB. Because you're actually retrievering records, so it looks like the filter is "broken" or "non-existing"
To query for a single record that is not in an array you should be using
findRecord(type,id)
peekRecord(type, id)
queryRecord(type, {query})
http://emberjs.com/blog/2015/06/18/ember-data-1-13-released.html

Ember.js not re-rendering template after Model loaded

I'm learning Ember.js using a Ruby on Rails API server. I've got the routes, template, and model all setup and working - but the template is never re-rendered once the data has been loaded from the API server. I'm not getting any error messages, and I know the customer is being loaded from looking at the Ember inspector.
Customer list is supposed to be displayed after start
Customer list is being loaded correctly from the API server:
Router
// javacripts/router.js
App.Router.map(function() {
this.resource('customers', { path: "/" });
});
Customers Route
// javascripts/routes/customer_routes.js
App.CustomersRoute = Ember.Route.extend({
model: function() {
return this.store.find('customer');
},
renderTemplate: function() {
this.render('customers/index');
}
});
Customer Model
// javascripts/models/customer.js
App.Customer = DS.Model.extend({
name: DS.attr('string')
});
Customer Index Template
// javacripts/templates/customers/index.js.handlebars
<ul>
<li>start</li>
{{#each customers}}
<li>{{name}}</li>
{{/each}}
</ul>
Store
// javacripts/store.js
App.ApplicationAdapter = DS.ActiveModelAdapter.extend({
namespace: 'api/v1'
});
Instead of
{{#each customers}}
It should read either
{{#each controller}}
{{name}}
{{/each}}
or
{{#each customer in controller}}
{{customer.name}}
{{/each}}
I have recently posted two screencasts. One showing how to get started with a new application, and one showing how to setup Grunt:
https://www.youtube.com/watch?v=T-s34EVSE_0
https://www.youtube.com/watch?v=kPaHt_F3VcU
You might also get some use out of a talk I gave earlier this year as well, which goes through developing a simple application during the talk, including Ember Data.
https://www.youtube.com/watch?v=KH5RreHtaaQ
Your customers/index template is referencing a "customers" collection that doesn't exist.
Your route's model hook is returning an array of records, which makes Ember generate an Ember.ArrayController with its model set to your array of customers. It doesn't have a property called "customers", so the {{#each customers}} doesn't have anything to iterate over. If you change it to just {{#each}} (because this in this scope references the controller, which is array-like) or {{#each model}} (to explicitly access the model array of the ArrayController), it should work correctly.
Also, your renderTemplate hook in the Route is the default behavior, so you can just delete it.
Incidentally, I'd recommend just using an Ember JSBin or something while you're starting out and learning the basics, so when you need to ask for help, you can just link to the bin, and people have live code they can work with to help you out, with a minimum of effort. That low barrier to entry makes a big difference to people who are doing free work for internet points.

Categories