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");
}
});
Related
I am using MEAN JS, i am trying to edit the list items on the list page, but it shows the error as below. i have initiated the data using ng-init="find()" for the list and ng-init="findOne()" for individual data.
Error: [$resource:badcfg] Error in resource configuration for action `get`. Expected response to contain an object but got an array
HTML
Below i the form inside the controller where it initiates the find() and findOne().
<div ng-controller="OrdersController" ng-init="find()">
<div>
<div class="order-filter">
<div ng-repeat="order in orders">
<form ng-init="findOne()" name="orderForm" class="form-horizontal" ng-submit="update(orderForm.$valid)" novalidate>
<input type="text" class="" ng-model="order.title">
<input type="text" class="" ng-model="order.content">
<div class="form-group">
<input type="submit" value="Update" class="btn btn-default">
</div>
</form>
</div>
</div>
</div>
</div>
Controller
$scope.update = function (isValid) {
$scope.error = null;
if (!isValid) {
$scope.$broadcast('show-errors-check-validity', 'orderForm');
return false;
}
var order = $scope.order;
order.$update(function () {
$location.path('orders/' + order._id);
}, function (errorResponse) {
$scope.error = errorResponse.data.message;
});
};
$scope.find = function () {
Orders.query(function loadedOrders(orders) {
orders.forEach(appendFood);
$scope.orders = orders;
});
};
$scope.findOne = function () {
$scope.order = Orders.get({
orderId: $stateParams.orderId
});
};
You need to check your Orders Service which probably is using $resource to provide your API requests (Orders.query)
It should look something like this:
function OrdersService($resource) {
return $resource('api/orders/:orderId', {
orderId: '#_id'
}, {
update: {
method: 'PUT'
}
});
}
The style may be different depending on which version of mean you're using. By default, the $resource query will expect an array of results, but if for some reason you've set "isArray" to false then it will expect an object.
https://docs.angularjs.org/api/ngResource/service/$resource
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 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();
}
});
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?