Meteor CollectionFs - download button don't works - javascript

I have a simple tickets app. When I create a new ticket, I can add attached file related to this one.
Download button don't works. Files metadata was correctly inserted into collection and I see it. Maybe, this is the reason: resources is not in the upload folder. I use the cfs:filesystem connector and here my code:
ticket.html
<head>
<title>orangeticket-test</title>
</head>
<body>
<h1>Tickets</h1>
{{> newTickets}}
{{> tickets}}
</body>
<template name="newTickets">
<input type="text" id="ticket" placeholder="name" >
<input id="submit" type="submit">
</template>
<template name="tickets">
{{#each tickets}}
<div class="tickets">
<p>Titolo: {{name}}</p>
{{> addFile}}
</div>
{{/each}}
</template>
<template name="addFile">
<form>
<input id="file" type="file">
<input id="addFile" type="submit">
</form>
{{#each files}}
<div class="file">
<strong>{{this.name}}</strong> Download
</div>
{{/each}}
</template>
tickets.js
Tickets = new Meteor.Collection('Tickets');
var fileStore = new FS.Store.FileSystem("fileStore", {
path: "~/uploads/files"
});
Files = new FS.Collection("Files", {
stores: [fileStore]
});
if (Meteor.isClient) {
Template.tickets.helpers({
tickets: function () {
return Tickets.find();
}
});
Template.newTickets.events({
'click #submit': function (e, t) {
e.preventDefault();
var ticket = t.find('#ticket').value;
Tickets.insert({name:ticket});
}
});
Template.addFile.events({
'click #addFile' : function(e, t){
var file = t.find('#file').files[0];
var ticket = this._id;
var newFile = new FS.File(file);
newFile.metadata = {
ticketId: ticket
};
Files.insert(newFile, function (err, fileObj) {
if (!err) {
console.log(fileObj);
}
});
}
});
Template.addFile.helpers({
files: function() {
var ticket = this._id;
return Files.find({'metadata.ticketId':ticket});
}
})
}
if (Meteor.isServer) {
Meteor.startup(function () {
console.log('server works');
});
}
clone git project:
git#gitlab.com:arcidiaco.a/orangeticket-test.git
thanks a lot!

I solved the problem: the submit button refresh the page while file was uploaded. This action interrupt the upload action. I deleted submit button and used instead only file input with change event:
Template.addFile.events({
'canche #file' : function(e, t){
var file = t.find('#file').files[0];
var ticket = this._id;
var newFile = new FS.File(file);
newFile.metadata = {
ticketId: ticket
};
Files.insert(newFile, function (err, fileObj) {
if (!err) {
console.log(fileObj);
}
});
}
});

Related

How to get data from meteor server in events with Meteor.js?

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>

How to show data from postgres in meteor

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();
}
});

How to create inputs that you can keep adding to a collection in meteor

I am trying to figure out how to create a form that has a input field, as well as a "+" button to add another input field. I than want to take those inputs and insert them into a collection. Than output them as a list. Basically I want to give the option to add as many list items as possible. If there is a better way to do this instead of a "+" button to add input fields,I' open to any suggestions.
code so far
HTML
<template name="postsList">
<div class="posts">
{{#each posts}}
{{> postItem}}
{{/each}}
</div>
</template>
<template name="postItem">
<h2>{{service}}</h2>
<ul><li>{{task}}</li></ul>
</template>
<template name="postSubmit">
<form>
<label for="service">Add a Service</label>
<input name="service" type="text" value="" placeholder="Service Type"/>
<label for="task">Add a task (spaces between each kind)</label>
<input name="task" type="text" value="" placeholder="type or task for service"/>
<input type="submit" value="Submit" />
</form>
</template>
JS
Template.postSubmit.events({
'submit form': function(e) {
e.preventDefault();
var post = {
service: $(e.target).find('[name=service]').val(),
task: $(e.target).find('[name=task]').val()
};
Meteor.call('post', post, function(error, id) {
if (error)
return alert(error.reason);
Router.go('postPage', {_id: id});
});
}
});
Posts = new Meteor.Collection('posts');
Posts.allow({
update: ownsDocument,
remove: ownsDocument
});
Posts.deny({
update: function(userId, post, fieldNames) {
// may only edit the following two fields:
return (_.without(fieldNames, 'service', 'task').length > 0);
}
});
Meteor.methods({
post: function(postAttributes) {
var user = Meteor.user(),
postWithSameLink = Posts.findOne({url: postAttributes.url});
// ensure the user is logged in
if (!user)
throw new Meteor.Error(401, "You need to login to post new stories");
// ensure the post has a service
if (!postAttributes.service)
throw new Meteor.Error(422, 'Please fill in a service');
// ensure the post has a task
if (!postAttributes.task)
throw new Meteor.Error(422, 'Please fill in a task');
// check that there are no previous posts with the same link
if (postAttributes.url && postWithSameLink) {
throw new Meteor.Error(302,
'This link has already been posted',
postWithSameLink._id);
}
// pick out the whitelisted keys
var post = _.extend(_.pick(postAttributes, 'service', 'task'), {
userId: user._id,
author: user.username,
submitted: new Date().getTime()
});
var postId = Posts.insert(post);
return postId;
}
});
Template.postsList.helpers({
posts: function() {
return Posts.find({}, {fields: {service: 1, task: 1}}).map(function(post, index) {
return post;
});
}
});

Extracting photos from FB-graph with Meteor

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));
});
}
});

meteor mrt collectionfs deploy

I use collectionfs for storing files in my application.
I copy+pasted most of the readme code provided with collectionfs into my application and also added the
{{cfsFileUrl "default1"}}
to my file listing. Everything works on my local machine.
The problem arises when I deploy to ???.meteor.com with
mrt deploy ???.meteor.com
I can upload and download images and also a url is displayed from cfsFileUrl,
BUT:
When I access that url, I get Error 404.
My code:
client.html
<body>
{{loginButtons}}
{{>queueControl}}
<br>ta
<br>
{{>fileTable}}
</body>
<template name="queueControl">
<h3>Select file(s) to upload:</h3>
<input name="files" type="file" class="fileUploader" multiple>
</template>
<template name="fileTable">
{{#each files}}
{{cfsDownloadButton "ContactsFS" class="btn btn-primary btn-mini" content=filename}}<br>
<img src="{{cfsFileUrl "default1"}}">
{{/each}}
</template>
client.js
ContactsFS = new CollectionFS('contacts', { autopublish: false });
Deps.autorun(function () {
Meteor.subscribe('myContactsFiles');
});
Template.queueControl.events({
'change .fileUploader': function (e) {
var files = e.target.files;
for (var i = 0, f; f = files[i]; i++) {
ContactsFS.storeFile(f);
}
}
});
Template.fileTable.files = function() {
//show all files that have been published to the client, with most recently uploaded first
return ContactsFS.find({}, { sort: { uploadDate:-1 } });
};
server.js
ContactsFS = new CollectionFS('contacts', { autopublish: false });
Meteor.publish('myContactsFiles', function() {
if (this.userId) {
return ContactsFS.find({ owner: this.userId }, { limit: 30 });
}
});
ContactsFS.allow({
insert: function(userId, file) { return userId && file.owner === userId; }
});
ContactsFS.fileHandlers({
default1: function(options) { // Options contains blob and fileRecord — same is expected in return if should be saved on filesytem, can be modified
console.log('I am handling default1: ' + options.fileRecord.filename);
console.log(options.destination());
return { blob: options.blob, fileRecord: options.fileRecord }; // if no blob then save result in fileHandle (added createdAt)
}
});
I had a similar problem and posted it on collectionfs issue page. Check it out: https://github.com/CollectionFS/Meteor-CollectionFS/issues/85

Categories

Resources