I'm trying to add a simple JS script to the server side of Meteor. Everywhere I read I'm told I should create an atmosphere package for the script-but that seems like a pretty round about way of doing it.
I am presently creating a local package to extend a feature on the app I'm using, and would like to use the script on the server side. Is there a way to simply REQUIRE a js file in meteor?
You can simple create server folder and add a js file to it.
Or you can use everywhere
if (Meteor.isServer)
{
//some servercode
}
more info about project structure http://meteortips.com/tutorial/structure-application/
The simple way to REQUIRE a js file in meteor is to put in the lib folder.
If it's required only by the front-end, then place it in the client lib folder (myproject/clinet/lib/requiredJSfile.js), if it's required by only the server, then place it in the server lib folder (myproject/server/lib/requiredJSfile.js).
If it will be used by both, put it in the root lib folder (myproject/lib/requiredJSfile.js).
You should do this, because the meteor rendering engine places the files from the lib folder on top of the inclusion list, meaning that when your actual meteor code runs it will be already available.
Check out this boilerplate for an example: https://github.com/matteodem/meteor-boilerplate
As a new user of Meteor it's not super clear here that, when creating a function to be included server-side you write it differently in Meteor.
Traditional .js function declaration would look something like:
function serverFoo(param1) {
console.log("serverFoo() param1="+param1);
return "bar";
}
The way to declare this function in Meteor:
Create a file "server/inc/server-globals.js".
var serverFoo = function(param1) {
console.log("serverFoo() param1="+param1);
return "bar";
}
Related
So im trying to build ontop of the angular-meteor WhatsApp clone tutorial using Ionic 2 CLI
This tutorial basically deletes the client folder in the meteor project and uses the meteor-client-side package inside an ionic project to connect to the meteor server.
Which works perfectly fine, but now i'd like to subscribe to a meteor publication with an reactive parameter.
After searching the Meteor API Documentation I found the Session object:
Session provides a global object on the client that you can use to
store an arbitrary set of key-value pairs. Use it to store things like
the currently selected item in a list.
What’s special about Session is that it’s reactive. If you
call Session.get("currentList") from inside a template, the template
will automatically be rerendered whenever
Session.set("currentList", x) is called.
In the Meteor Subscribe Documentation you can find the following example:
Tracker.autorun(function () {
Meteor.subscribe("chat", {room: Session.get("current-room")});
Meteor.subscribe("privateMessages");
});
This subscribes you to the chat messages in the current room and to
your private messages. When you change rooms by
calling Session.set("current-room", "new-room"), Meteor will subscribe
to the new room’s chat messages, unsubscribe from the original room’s
chat messages, and continue to stay subscribed to your private
messages.
Which is exactly what I want to do too. But as the Session documentation states, session is a package I have to add to the meteor project:
To add Session to your application, run this command in your terminal:
meteor add session
Now my question, is there any way to add session to the meteor-client-side packages?
If I just try to call Session.set() it fails on runtime with Session is not defined
My guess is that I would need some npm package that extracts the Session functionality (basically a sessions-client-side npm package) like accounts-base-client-side
Is there an other way to do this?
How would I build my own sessions-client-side?
I tried to run meteor add session in my meteor project but was not able to find the code for Session anywhere in .meteor folder and npm_modules.
I also looked into the meteor GitHub but the Session.js file they have contains only documentation
Any input how to do something like this would be nice
Update:
I've looked into the accounts-base-client-side package and found out that they are autogenerated using a script, so im currently trying to adapt this script to work with Session instead of accounts-base.
You can find my attempt at: https://github.com/AwsmOli/session-client-side
Still work in progress, but i should get it to work soon
Update 2:
See my answer, my session-client-side is working now :)
The "Session" variable should just appear and be accessible. If you need to verify that, start a new project add the package and write some code to access it. It is likely that something has (unwittingly) nuked the Session variable - I have seen this before with another package.
Another way of doing this is with "getReactively". Below is a helper that uses it in a query. Make sure you declare it before the helper (otherwise it won't work). This one uses the result of another helper, but it can be any variable, and you just assign the variable for the reactivity to kick in and run the helper.
this.helpers({
currentUser: () => { return Meteor.user() },
elder: () => {
let e = Elders.findOne({_id: this.getReactively('this.currentUser._id')});
if (e) {
utils.services.setupElder(e);
}
return e;
}
});
As per the meteor docs, you have to import it:
import { Session } from 'meteor/session'
This will enable it on the client.
In earlier meteor versions this was not required, as it was both a default package, and automatically imported into the global namespace.
I ended up creating the session-client-side package myself, and its working nicely.
If you need it too, its available on GitHub:
https://github.com/AwsmOli/session-client-side
and NPM:
npm install session-client-side
credits to idanwe who created the client side packages and made it realy easy to adapt his work to work with any meteor package :)
To use it with Ionic 2 Apps:
import it in your entry points (src/app/main.prod.ts & src/app/main.dev.ts)
import 'session-client-side';
and now the global Session variable is accessable form anywhere in your app:
Session.set("aCoolNameFormyAwsmChangingObject", myAwsmChangingObject);
Thanks for the help!
I'm building a meteor package I noticed that in a package even if I put my code in server directory the code runs # the client . What's the pattern used in packages to separate code ? Should I rely only on wrapping the code with Meteor.isServer ? Is there a configuration for package.js ?
Packages do not rely on application level specific file structure responsible for conditional loading and load order, on the contrary you have to specify which files are loaded first and on which architecture.
You can do so using the Packages API, in particular use this :
https://docs.meteor.com/#/full/pack_addFiles
Package.onUse(function(api){
// ...
api.addFiles("server/server.js","server");
// ...
});
There is nothing preventing you to adopt the application file structure with client/server directories, just remember that it has no impact on actual file adding/loading control logic.
I am trying to import a js file into Meteor, named DomLoader.js, that uses the XMLHttpRequest object. If I try to load the file inside a Meteor package like so:
Package.on_use(function(api) {
api.add_files('DomLoader.js', 'client');
// more add_files and export statements
}
There is an error because XMLHttpRequest is undefined in the DomLoader.js file. How am I supposed to obtain this object? One possible way would be to use one from Npm, but I am not sure whether that one behaves exactly the same as the one in the browser.
Meteor uses a different HTTP module, more info here.
XMLHttpRequest in your JS file can be replaced with the HTTP.call(...) function that Meteor provides.
In Meteor is there a way to include a js file in another js file.
Specifically, server side and most importantly at start up.
The use case I am running into is for complicated Meteor.startups where I need to load quite a bit of data to the mongodb into a variety of collections.
In order to have different test scripts I have to have more than one file each with duplicate data.
So, is there anyway to have say a boostrap.js file that calls Meteor.startup and then is able to load different files in order to load up the test data?
Or can this be done in a different way through some kind of object?
By design Meteor will automatically include all the javascript files in the the entire project (except in the public folder) but only segregate them between the server and client.
You could create objects in separate files and just use the functions or objects whenever you please, they should all be available at startup.
Try using my module loader made for use with Meteor. It's very similar to AMD: https://github.com/matb33/meteor-smd
Copying a static website, i.e., HTML, CSS, JS is very simple.
Copying a dynamic website, i.e., is difficult due to the server-side scripts.
I'm concerned about cloning any meteor app as most of the server-side scripts are eliminated and the only thing which needs to be copied is the database, the schema can be easily obtained from the meteor live app and data can be easily scraped from the existing meteor app.
If a successful meteor app can be easily cloned, no one would prefer to develop an app on meteor.
Is there a way to stop cloning an existing meteor app?
Well, technically a meteor app can be cloned it depends on your directory/file structure & whether you're using it in development mode. If you're using one file and this sort of structure to seperate your code:
if(Meteor.isClient) {
}
if(Meteor.isServer) {
}
Because this file would be sent down to the client so someone can fetch it.
So it might be better to move to this structure
/client - Place stuff in Meteor.isClient in a new js file
/server - Place your server side code in a new js file
/public - Place other public folder stuff
So no one will see the server side scripts, so they can't clone the backend of your app.
Production mode/Dev mode
In addition if you run your Meteor app in 'production mode' the Javascript is packed, handlebars & handlebars templates are precompiled.
In my opinion, it might be actually harder to copy a Meteor app to the previous types of web apps because HTML is rendered on the client side, fetching the html files will actually get back empty html files, if you even prettify the large JS file still leaves back precompiled handlebars templates. In addition files are merged into one!
So thats when it comes to cloning it to another meteor app. Even if getting the client script is available (as with any other stack) there are even more hurdles with Meteor when it comes to replicating the server script:
DDP
Attempting to clone it to a PHP/Server side script stack might be even harder because POST/GET aren't even used, DDP is used instead.
Schema
Width regards to the schema, you can control what the client sees via Meteor.publish, so they won't actually see the whole schema