I am using meteor-postgres and want to display results from SQL query.
Html:
...
<template name="myForm">
<form class="search" method="GET">
<input required="Required" type="text" name="width" placeholder="cm"/>
<input type="submit"/>
</form>
Results:
<ul>
<!--How do I render results here-->
</ul>
...
JS
Services = new SQL.Collection('services');
// in client
Template.myForm.events({
"submit form": function (event) {
var width = event.target.width.value;
// TypeError: table is undefined,
// Maybe because I am on client side?
console.log(services.first().fetch());
// How can I get data here and render it to html?
}
});
I dont know what else should I say but StackOverflows want me to add more text!
I decided to use https://github.com/numtel/meteor-pg because it has nice examples.
Update
It is better and simpler to use PgSubscription.change:
Template:
<template name="hello">
<label>id</label>
<input type="number" id="myid" />
{{#each services}}
{{id}}
{{/each}}
</template>
JS
myServices = new PgSubscription('services');
if (Meteor.isClient) {
Template.hello.helpers({
services: function () {
return myServices.reactive();
}
});
function handleInput(event, template) {
var idVal = template.find("#myid").value;
console.log("client change detected, new value:");
console.log(idVal);
myServices.change(idVal);
}
Template.hello.events({
"keyup #myid": function(event,template) {
handleInput(event,template);
},
"change #myid": function(event,template) {
handleInput(event,template);
}
});
}
if (Meteor.isServer) {
var PG_CONNECTION_STRING = "postgres://root:root#localhost:5433/parcelService";
var liveDb = new LivePg(PG_CONNECTION_STRING, "myApp");
var closeAndExit = function () {
liveDb.cleanup(process.exit);
};
// Close connections on hot code push
process.on('SIGTERM', closeAndExit);
// Close connections on exit (ctrl + c)
process.on('SIGINT', closeAndExit);
Meteor.publish('services', function (id) {
console.log("server services, id:");
console.log(id);
return liveDb.select(
'SELECT * FROM services WHERE id = $1', [ id ]
);
});
}
Old Method:
On client side I defined ReactiveVar for template
Template.myForm.created = function () {
this.asyncServices = new ReactiveVar(["Waiting for response from server..."]);
}
and helper for data
Template.myForm.helpers({
myData: function () {
return Template.instance().asyncServices.get();
}
});
now trigggering action with
Template.myForm.events({
'keyup input': function (evt, template) {
var asyncServicesX = Template.instance().asyncServices;
Meteor.call('services', params, function(error, response){
if (error) throw error;
asyncServicesX.set(response);
});
}
And finally method on server side, where sql is executed:
Meteor.methods({
'services': function (params) {
Future = Npm.require('fibers/future');
var future = new Future();
// Obtain a client from the pool
pg.connect(PG_CONNECTION_STRING, function (error, client, done) {
if (error) throw error;
// Perform query
client.query(
'select * from services where col1=$1 and col2=$2',
params,
function (error, result) {
// Release client back into pool
done();
if (error) throw error;
future["return"](result.rows);
}
)
});
return future.wait();
}
});
Related
I want to get the data or document for meteor server in event.
Someone has the other solution from this.
// meteor in server
Meteor.methods({
findPost: function() {
return Post.find().fetch();
}
}
});
//client template
<template name="Demo">
<input type="text" id="input-test">
<button id="test">Test</button>
</template>
//client event
Template.Demo.events({
'click #test':function(){
Meteor.call('findPost',function(error,result){
if(result) {
Session.set('foundPosts',result);
}
}
var posts=Session.get('foundPosts');
if(posts.length>0){
$('#input-test').val('Found');
}else{
$('#input-test').val('No result');
}
}
});
In this example I use the session to get value for meteor method callback function so that I can use it to do something else outside the method callback function. Do someone have better solution to get value from method callback function or have other solution to get data from meteor server in template event.
Template.Demo.onCreated(function () {
this.inputValue = new ReactiveVar('No result');
})
Template.Demo.events({
'click #test': function () {
var tmpl = Template.instance();
Meteor.call('findPost', function (err, res) {
if (!err && res.length > 0) {
tmpl.inputValue.set('Found');
}
});
}
});
Template.Demo.helpers({
inputVal: function () {
var tmpl = Template.instance();
return tmpl.inputValue.get();
}
});
//client template
<template name="Demo">
<input type="text" id="input-test" value="{{inputVal}}">
<button id="test">Test</button>
</template>
I am using MeteorJS to develop simple web app. I am new at MeteorJs. I use useraccounts:core package and meteor-roles by alanning. Is it posible to assign role to user while registering a new user ?
EDIT 1
I have tried using onCreateUser hook but something is not working.
Accounts.onCreateUser(function(options, user){
var role = ['unselected'];
Roles.addUsersToRoles(user, role);
return user;
});
The below method must run on the server side only. The clue is that you need to create first the user, get the id from creation and then attach a role to it.
Meteor.methods({
rolesCreateUser: function (user) {
if (_.isObject(user)) {
if (user.username) {
var id = Accounts.createUser({
username: user.username,
email: user.email,
password: user.password
});
//We add roles to the user
if (user.roles.length > 0) {
Roles.addUsersToRoles(id, user.roles);
}
_.extend(user, {id: id});
return user;
}
}
}
});
And then on the client side call the method with user's data:
Meteor.call('rolesCreateUser', newUserData, function (error, newCreatedUser) {
if (error) {
//The error code
} else {
//Do something with newCreatedUser
}
});
I have this way to create users (if i understond you example you alredy have some users, just need some roles, so with the current user just create this), also use some Login buttons customized or something like that
Server.js
Meteor.methods({
createUsers: function(email,password,roles,name){
var users = [{name:name,email:email,roles:[roles]},
];
.each(users, function (user) {
var id;
id = Accounts.createUser({
email: user.email,
password: password,
profile: { name: user.name }
});
if (user.roles.length > 0) {
Roles.addUsersToRoles(id, user.roles);
}
});
},
deleteUser : function(id){ ///Some Delete Method (ignore if dont needed)
return Meteor.users.remove(id);
},
});
Publish Methods
//publish roles
Meteor.publish(null, function (){
return Meteor.roles.find({})
})
Meteor.publish("Super-Admin", function () {
var user = Meteor.users.findOne({_id:this.userId});
if (Roles.userIsInRole(user, ["Super-Admin"])) {
return Meteor.users.find({}, {fields: {emails: 1, profile: 1, roles: 1}});
}
this.stop();
return;
});
Meteor.publish("Admin", function () {
var user = Meteor.users.findOne({_id:this.userId});
if (Roles.userIsInRole(user, ["Admin"])) {
return Meteor.users.find({}, {fields: {emails: 1, profile: 1, roles: 1}});
}
this.stop();
return;
});
Meteor.publish(null, function (){
return Meteor.roles.find({})
})
So on the Client side client/register.html
<template name="register">
<form id="register-form" action="action" >
<input type="email" id="register-email" placeholder="Nombre Nuevo Usuario">
<input type="password" id="register-password" placeholder="Password">
<select id="register-rol" class="form-control">
<option value="Admin" selected>Admin</option>
<option value="Super-Admin" selected>Super Admin</option>
<option value="Normal" selected>Normal</option>
</select>
<input type="submit" value="Register">
</form>
</tempalate>
and on register.js call the server methods
Template.registrar.events({
'submit #register-form' : function(e, t) {
e.preventDefault();
var email = t.find('#register-email').value,
password = t.find('#register-password').value,
roles = $( "#register-rol" ).val();
Meteor.call("createUsers", email, password,roles);
return false;
},
'click #deleteUser' : function(event,template){
var idUsuario= this._id;
Meteor.call('deleteUser',{_id:idUsuario})
}
});
Delete Part(html) this is optional just too look if accounts are creating correctly
{{#each users}}
<li id="user"><h6>{{email}}</h6><h6>{{roles}}</h6></li>
<button id="deleteUser" class="btn btn-danger btn-xs" > Borrar Usuario {{email}} </button>
{{/each}}
client/registerList.js
Template.registrar.helpers({
users: function () {
return Meteor.users.find();
},
email: function () {
return this.emails[0].address;
},
roles: function () {
if (!this.roles) return '<none>';
return this.roles.join(',');
}
});
Remember Subscribe
Meteor.subscribe('Admin');
Meteor.subscribe('Super-Admin');
Hope this help sorry for the messy code
You may want to use OnCreateUser hook: http://docs.meteor.com/#/full/accounts_oncreateuser
I want to use x-editable-reactive-template in my MeteorJS project. My template looks like this:
<template name="jobSeeker">
<div class="items-form">
{{> xEditable type="text" success=onSuccess placement="right" mode="inline emptytext="Your name..." value=usernameValue }}
</div>
</template>
My template helper looks like this:
Template.jobSeeker.helpers({
usernameValue: function()
{
Meteor.call('getProfileUsername',function(error, result) {
if (error) return alert(error.reason);
return result;
});
}
});
Meteor method on server-side:
Meteor.methods({
getProfileUsername: function() {
var user = Meteor.user();
var currentUsername = Meteor.users.findOne(user._id);
return currentUsername.username;
}
});
User is saved in MongoDB and inside collection there is document with field username. But something isn't working! Any help ?
you are returning value inside a method callback that will not return value to the helper
try this
Template.jobSeeker.helpers({
usernameValue: function()
{
Meteor.call('getProfileUsername',function(error, result) {
if (error)
return alert(error.reason);
Session.set("username",username);
});
return Session.get("username");
}
});
I'm trying to display photos from the NPM FB-Graph (https://npmjs.org/package/fbgraph) package by following this example (http://www.andrehonsberg.com/article/facebook-graph-api-meteor-js). I've managed to connect the API and render data, however I'm having trouble extracting the EJSON data into my picture template.
First off, let me show you the code I'm working with. Here is my client code:
function Facebook(accessToken) {
this.fb = Meteor.require('fbgraph');
this.accessToken = accessToken;
this.fb.setAccessToken(this.accessToken);
this.options = {
timeout: 3000,
pool: {maxSockets: Infinity},
headers: {connection: "keep-alive"}
}
this.fb.setOptions(this.options);
}
Facebook.prototype.query = function(query, method) {
var self = this;
var method = (typeof method === 'undefined') ? 'get' : method;
var data = Meteor.sync(function(done) {
self.fb[method](query, function(err, res) {
done(null, res);
});
});
return data.result;
}
Facebook.prototype.getUserData = function() {
return this.query('me');
}
Facebook.prototype.getPhotos = function() {
return this.query('/me/photos?fields=picture');
}
Meteor.methods({
getUserData: function() {
var fb = new Facebook(Meteor.user().services.facebook.accessToken);
var data = fb.getPhotos();
return data;
}
});
Meteor.methods({
getPhotos: function() {
var fb = new Facebook(Meteor.user().services.facebook.accessToken);
var photos = fb.getPhotos;
return photos;
}
});
Here is my client code:
Template.fbgraph.events({
'click #btn-user-data': function(e) {
Meteor.call('getUserData', function(err, data) {
$('#result').text(JSON.stringify(data, undefined, 4));
});
}
});
var fbPhotos = [];
Template.fbgraph.events({
fbPhotos : function(e) {
Meteor.call('getUserData', function(err, data) {
$('input[name=fbPhotos]').text(EJSON.stringify(data, undefined, 4));
});
}
});
Template.facebookphoto.helpers({
pictures: fbPhotos
});
And here are my templates:
<template name="fbgraph">
<div id="main" class="row-fluid">
{{> facebookphoto}}
</div>
<button class="btn" id="btn-user-data">Get User Data</button>
<div class="well">
<pre id="result"></pre>
</div>
</template>
<template name="facebookphoto">
<div class="photos">
{{#each pictures}}
{{> photoItem}}
{{/each}}
</div>
</template>
<template name="photoItem">
<div class="photo">
<div class="photo-content">
<img class="img-rounded" src="{{picture}}">
</div>
</div>
</template>
Right now, I'm testing the data with the id="results" tag and the Facebook API returns data as below.
{
"data": [
{
"picture": "https://photo.jpg",
"id": "1234",
"created_time": "2013-01-01T00:00:00+0000"
},
{
"picture": "https://photo.jpg",
"id": "12345",
"created_time": "2013-01-01T00:00:00+0000"
}
}
However I'm having difficulty pulling each of the pictures out of the EJSON and render them in templates. What I'd like to do is to display each picture in the {{picture}} template. I believe the problem with the code is somewhere in the client, but I'm not sure how to fix it.
Thanks in advance!
It looks like in your client code you have
Template.fbgraph.events({ ... })
defined twice. Did you mean to write:
Template.fbgraph.helpers({
fbPhotos : function(e) {
Meteor.call('getUserData', function(err, data) {
$('input[name=fbPhotos]').text(EJSON.stringify(data, undefined, 4));
});
}
});
A simpler way to do it might just be to call the getUserData method in your facebookphoto template itself, thus:
Template.facebookphoto.helpers({
pictures : function(e) {
Meteor.call('getUserData', function(err, data) {
$('input[name=fbPhotos]').text(EJSON.stringify(data, undefined, 4));
});
}
});
I've been looking at this for awhile and I'm pretty sure it has something to do with an infinite callback loop.
I have a method that returns an integer from a collection called Sessions. Here are my methods:
Meteor.methods({
going: function(sessionsId) {
return Sessions.update(sessionsId, {$addToSet: {participants: Meteor.userId()}, $inc: {slots:-1}});
},
retract: function(sessionsId) {
return Sessions.update(sessionsId, {$pull: {participants: Meteor.userId()}, $inc: {slots:1}});
},
sessionFull: function(sessionsId) {
var session = Sessions.findOne({_id:sessionsId});
console.log("gets here");
return session.slots;
}
});
Then in my client I have:
if (Meteor.isClient) {
Template.hello.sessions = function () {
return Sessions.find();
};
Template.session.this_info = function () {
return this._id;
};
Template.session.isGoing = function() {
var session = Sessions.find({_id:this._id, participants:Meteor.userId()}).count();
if (session > 0) return true;
else return false;
};
Template.session.sessionFull = function() {
if (this.slots === 0) return true;
else return false;
};
Template.session.slotsMethod = function () {
Meteor.call('sessionFull',this._id, function(error, slots) {
Session.set("slots",slots);
});
return Session.get("slots");
};
Template.session.events({
'click input.going' : function () {
//Sessions.update(this._id, {$inc: {slots: -1}});
Meteor.call('going', this._id, function(error, updated) {
if (error)
return alert(error.reason);
});
},
'click input.retract' : function () {
Meteor.call('retract', this._id, function(error, removed) {
if (error)
return alert(error.reason);
});
}
});
So I basically have a couple buttons that will increase or decrease the slots field and I want to have a method that will return what the slots field contains. Here is my template:
{{#each sessions}}
{{> session}}
{{/each}}
<template name="session">
<br>
{{date_time}}, {{duration}}
{{#if isGoing}}
<input type="button" class="retract" value="not going/give slot" />
{{else}}
{{#if sessionFull}}
<h1>SORRY SESSION FULL</h1>
{{else}}
<input type="button" class="going" value="going/subract slot" />
{{/if}}
{{/if}}
{{participants}},{{sessionFull}},{{this_info}}
</template>
If I try to add the Template.session.slotsMethod to my template (which calls the sessionFull Meteor method) I get an infinite loop, as in, it will display a rapidly changing integer for each session.
Am I doing something wrong?? Can't figure it out, I think it has something to with callbacks/async/sync but not sure.
Yes, your Template.session.slotsMethod will cause an infinite loop since Session is reactive.
This is what happens:
Whenever Session.get("slots") changes, Template.session.slotsMethod will be called because its dependent on Session.get("slots").
However, Template.session.slotsMethod itself is also updating the value of Session.get("slots") so the process starts all over again.
Not quite sure when you want Template.session.slotsMethod to be run, but you probably want to break it up into two pieces, something like:
Template.session.getSlots = function () {
return Session.get("slots");
};
and
Meteor.call('sessionFull',this._id, function(error, slots) {
Session.set("slots",slots);
});
needs to go wherever/whenever you need to do the sessionFull check, perhaps in Template.session.rendered?