Meteor - file download with meteor-files package ( ostrio:files) - meteor

I would need some help with meteor-files package
I'm following the simplest-download DEMO here https://github.com/VeliovGroup/Meteor-Files/tree/master/demo-simplest-download-button and getting on a few bumpers. First here is the code:
this.Books = new Meteor.Files({
debug: true,
collectionName: 'Books'
});
// To have sample file in DB we will upload it on server startup:
if (Meteor.isServer) {
Books.denyClient();
Books.collection.attachSchema(Books.schema);
Meteor.startup(function () {
if (true) {
Books.load('http://localhost:3000/file.pdf', {
fileName: 'file.pdf',
meta: {}
});
}
});
Meteor.publish('Books', function () {
return Books.find().cursor;
});
} else {
Meteor.subscribe('Books');
}
Problem - When I c/p the code from the git then there is this condition if
(!Images.find().count())
which meteor just doesn't recognize as a function and breaks there. I fixed that with just replacing it with TRUE as you can see in code
Problem is that now everything runs and my file is successfuly imported but I can see in the server log that he is not able to find the file resulting in:
[FilesCollection] [load] Received: http://localhost:3000/file.pdf
I20160806-14:00:27.190(2)? [FilesCollection] [load] [insert] file.pdf -> Books
I20160806-14:00:29.360(2)? [FilesCollection] [find(undefined)]
I20160806-14:00:33.045(2)? [FilesCollection] [find(undefined)]

The package was out of date and needed a meteor update from my side. If someone will need

Related

JSZip and cfs:collection in Meteor app

So, Im using udondan:jszip, cfs:collection,
cfs:standard-packages and
cfs:filesystem packages in my meteor app. The problem is that I cant store my zip files in the FS.COllection. Here is some of the code :
//Defining the collection
Reports = new FS.Collection('reports',{
stores: [new FS.Store.FileSystem('reports', {path: "~/public"})]
});
//Trying to add a file to the collection
var zip = new JSZip();
Reports.insert(zip);
After running the code Im getting this error:
Error: DataMan constructor received data that it doesn't support
Is there any way to make those packages work with each other ?
The JSZip object is not a file by itself. You can generate a file from it with the generateAsync function. The file type you'll want to create depends on if you want this to run on the client or server and how you want to use this file. The file types supported by both libraries are: (as per documentation, I haven't tested all these myself)
Blob object (client only): { type: 'blob' }
Uint8Array: { type: 'uint8array' }
ArrayBuffer: { type: 'arraybuffer' }
Buffer object (server only): { type: 'nodebuffer' }
So for example this should work:
zip.generateAsync({ type: 'arraybuffer' })
.then(function (content) {
Reports.insert(content);
});

Meteor audit-argument-checks

I have a Meteor project where I'm using audit-argument-check. I'm getting an error message
Error: Did not check() all arguments during publisher 'document
I'm know this is related the audit-argument-check not being able to check all arguments. But as far as I'm concerned, I checked all of them. Concrete, I have defined a collection 'documents' and attached a SimpleSchema. As part of iron-router, I have the following:
Router.route('customerDocumentShow', {
template: 'customerDocumentShow',
path: 'customer/documents/:_id',
waitOn: function () {
return Meteor.subscribe('document', this.params._id);
},
data: function () {
return Documents.findOne(this.params._id);
}
});
So I'm passing only the documentId (this.params._id). On the server, I have defined a method:
Meteor.methods({
documentsReadMethod: function(documentId){
check(documentId, String);
var documentItem = Document.findOne(argument);
if (!documentItem) {
throw new Meteor.Error(500, 'Error 500: Not Found', 'No documents found.');
}
return documentItem;
}
});
So I'm checking to documentId in the server method. So not sure why I'm getting this error message.
Note: One thing I'm not entirely sure about though is how I need to call this method (right now, it's documentsReadMethod_. I'm not explicitly calling (on the client):
Meteor.call(documentsReadMethod, this.params_id);
as I'm using autoform, collection2 and simpleschema. I've been spending the entire weekend, but have no clue. Any idea's ?
Note: the code is on github: https://github.com/wymedia/meteor-starter-base
The problem is in the publish. You didn't check the id here:
https://github.com/wymedia/meteor-starter-base/blob/master/server/publications/documents.js#L16
Just add check(id, String); line 16 and it should work.
I have the same problem with another tuto !
Answer found at check is not defined in meteor.js : since Meteor v1.2, you have to add this package:
$ meteor add check

Meteor/Iron-Router: how to define routes using data from settings.json

For the URL to which a route applies I have a part defined in settings.json, like this
baseUrl: '/private'
My settings are published and accessible through the collections 'Settings' (on the client). So I tried the following:
Meteor.subscribe('settings');
Deps.autorun(function () {
var settings = Settings.findOne():
if (settings) {
Router.map(function () {
this.route('project', {
path: settings.baseUrl + '/:projectId,
controller: 'ProjectController'
});
});
}
});
The problem is that during initialisation the data is not yet on the client available, so I have to wait until the data is present. So far this approach doesn't work (yet). But before spending many hours I was wondering if someone has done this before or can tell me if this is the right approach ?
Updated answer:
I published solution in repository : https://github.com/parhelium/meteor-so-inject-data-to-html
. Test it by opening url : localhost:3000/test
In this case FastRender package is useless as it injects collection data in the end of head tag -> line 63.
Inject-Initial package injects data in the beginning of head tag -> line 106.
Needed packages:
mrt add iron-router
mrt add inject-initial
Source code:
Settings = new Meteor.Collection("settings");
if (Meteor.isClient) {
var settings = Injected.obj('settings');
console.log(settings);
Router.map(function () {
this.route('postShow', {
path: '/'+settings.path,
action: function () {
console.log("dynamic route !");
}
});
});
}
if (Meteor.isServer){
if(Settings.find().count() == 0){
Settings.insert({path:"test",data:"null"});
}
Inject.obj('settings', Settings.findOne());
}
Read about security in the bottom of the page : https://github.com/gadicc/meteor-inject-initial/
OLD ANSWER :
Below solution won't work in this specific case as FastRender injects data in the end of head tag. Because of that Routes are being initialized before injected data is present.
It will work when data from Settings collection will be sent together with html.
You can do that using package FastRender.
Create file server/router.js :
FastRender.onAllRoutes(function(path) {
// don't subscribe if client is downloading resources
if(/(css|js|html|map)/.test(path)) {
return;
}
this.subscribe('settings');
});
Create also publish function:
Meteor.publish('settings', function () {
return Settings.find({});
});
The above code means that if user open any url of your app then client will subscribe to "settings" publication and data will be injected on the server into html and available for client immediately.
I use this approach to be able to connect many different domains to meteor app and accordingly sent proper data.

Load an external file in a grunt-contrib-jade task

So I've got this grunt-contrib-jade setup that is working just fine
Everything is fine when I include my data in the (exported) Gruntfile myself:
module.exports = {
website: {
options: {
data: {
pageTitle: "This is my website",
greeting: "Hello world",
},
debug: true,
pretty: true
},
files: {
'build/website/index.html': 'src/jade/template/index.jade'
}
}
};
It merges my index.jade with my data values and my index.html output is the way it should be. But when I want to load an external file to define my data it goes wrong:
options: {
data: function (dest, src) {
// Return an object of data to pass to templates
return require('src/jade/template/locals.json');
},
debug: true,
pretty: true
},
files: {
'build/website/index.html': 'src/jade/template/index.jade'
}
The require path is valid, I triple checked it. It's located in the same folder as my index.jade. However I still keep getting this error:
Running "jade:website" (jade) task
>> Jade failed to compile "src/jade/template/index.jade".
>> Error: Cannot find module './locals.json'
>> Destination not written because compiled files were empty.
I tried just about everything, but I just don't see it.
Local modules need to be prepended with './' when you require them.
data: function (dest, src) {
// Return an object of data to pass to templates
return require('./src/jade/template/locals.json');
}
will work. You're not doing anything with the function (at least yet), so this could also be
data: require('./src/jade/template/locals.json')
or even
data: grunt.file.readJSON('./src/jade/template/locals.json').

How can I implement a call to a package that doesn't use fibers from with Meteor?

I am trying to use twit in Meteor in order to communicate to the Twitter REST api.
It works fine in say a server.js file in the /server/ directory if I call it by itself. If I wrap or call it from within say an observe or even call a function that calls twit's functions from an observe I get errors.
For example this works perfectly fine within a /server/server.js.
T.post('statuses/update', { status: 'hello world!' }, function(err, reply) {
console.log('error: ' + JSON.stringify(err,0,4));
console.log('reply: ' + JSON.stringify(reply,0,4));
});
But, suppose I want to say call Twitter every time a record is inserted.
var query = Posts.find({}, {fields: {}});
var handle = query.observe({
added: function(post, before_index){
if(post.twitter_id_str === undefined || post.twitter_id_str === '' ||
post.twitter_id_str === null) {
T.post('statuses/update', { status: 'hello world!' }, function(err, reply) {
console.log('error: ' + JSON.stringify(err,0,4));
console.log('reply: ' + JSON.stringify(reply,0,4));
if(reply){
// TODO update record with twitter id_str
// BREAKS here - crash, restart
console.log('incoming twitter string: ' + reply.id_str);
Posts.update(
{_id: post._id},
{$set:{twitter_id_str:reply.id_str}}
);
}
});
} else {
console.log('remove me we have it: ' + post.twitter_id_str);
}
}
});
Which throws this error, server crashes and restarts but no code logic is run where I have commented the Break.
app/packages/mongo-livedata/collection.js:215
throw e;
^
Error: Meteor code must always run within a Fiber
at [object Object].get (app/packages/meteor/dynamics_nodejs.js:14:15)
at [object Object]._maybeBeginWrite (app/packages/mongo-livedata/mongo_driver.js:68:41)
at [object Object].update (app/packages/mongo-livedata/mongo_driver.js:191:20)
at [object Object].update (app/packages/mongo-livedata/collection.js:203:32)
at app/server/server.js:39:13
at /usr/lib/meteor/lib/node_modules/twit/lib/oarequest.js:85:16
at passBackControl (/usr/lib/meteor/lib/node_modules/twit/node_modules/oauth/lib/oauth.js:359:11)
at IncomingMessage.<anonymous> (/usr/lib/meteor/lib/node_modules/twit/node_modules/oauth/lib/oauth.js:378:9)
at IncomingMessage.emit (events.js:88:20)
at HTTPParser.onMessageComplete (http.js:137:23)
Exited with code: 1
In summary, the Twitter code runs fine on it's own but not when within the Meteor fibers stuff. I tried putting it in another function and calling that from within the observe etc... no avail.
Any recommendations or ideas?
You'll need to do the twit post API call in a fiber:
Fiber(function() { ... your twit API call ... }).run()
Have a look at this related question: "Meteor code must always run within a Fiber" when calling Collection.insert on server

Resources