Using the XMLHttpRequest object in a Meteor package - meteor

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.

Related

Meteor: session-client-side

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!

Meteor with dotenv package for environment variables: "process" is not defined

I'm adding security for my API keys with the Meteor package dotenv: https://github.com/okgrow/meteor-dotenv
as per instructions, I:
1. created a file named ".env" in my root
2. entered two keys in the style "THIS_KEY=BLAH12345" in the file
3. made a meteor call function returning process.env.THIS_KEY for the client side to use.
I'm getting Referenceerror: process.env is not defined. For just plain node there are a lot of answers out there, but not so for Meteor. Did I name my file incorrectly? Need to use a Meteor command to activate something?
I ran into this same problem, and have made it work by putting the
var secretThing = process.env.SECRET_THING
server side, inside the if (Meteor.isServer) and then passing the variable as a parameter to the method that needs to use the secret thing.
Meteor.call("apiCall", secretThing);
Then the receiving method looks like this:
apiCall: function (secretThing) {
console.log(secretThing);
}
DotEnv is designed to read environment variables from a .env file, normally located in the root of your NodeJS application.
DotEnv just makes the variables it finds in the .env file available with the rest of the host systems environment variables through process.env
The problem is, I don't believe meteor supports .env files. This is probably due to the age of the application. I personally believe they should make rectifying this a priority.
The only way you can use process.env in a meteor app is to set the variables you want to use on the host system. If you are using linux it would be something like
export DB_PASSWORD=12345
You should then be able to use process.env to read DB_PASSWORD when your application is running.
// You can only run process.env in server code
if (Meteor.isServer) {
const myDBPassword = process.env.DB_PASSWORD
}

Host TimeLineJS on Meteor app without smart package

I'd like to host the TimeLineJS library on my Meteor app locally and not use the smart package because I need to fine tune it. I've tried declaring the createStoryJS function in the Meteor space like this in create Timeline.js. However, there are other dependencies (storyjs-embed.js, storyjs-embed-generator.js, storyjs-embed.js, and everything under locale) which rely on the document object on the browser. How can I ensure that Timeline.js is loaded in a template with all of its dependencies locally managed, while successfully accessing the window.document object?
Put all the files in client/compatibility in your app, such that the dependencies load first via Meteor’s load order (e.g. put dependencies in client/compatibility/lib, for example). That’s all you have to do: no script tags, no declaring anything. Initialize TimeLineJS within a template’s onRendered callback.

Add simple server side JS file to meteor

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

Using Handlebars util methods in Meteor server

I'm working on my first Meteor app, and I'm trying to escape a string on the server side. I was hoping to use Handlebars.Utils.escapeExpression, but even when I add handlebars (which I had to do, even though Meteor already uses it?), I still get
ReferenceError: Handlebars is not defined
error when that code is hit. Is there a way to invoke that method server side without manually including the source in my project?
Meteor uses Handlebars on the client only. Server-side rendering is on the roadmap.
Also, the Handlebars that comes with Meteor doesn't include Utils.
Use {{{thingThatNeedsEscaping}}} instead, as per the documentation that unescapes it.
Also, I don't think it's necessary to escape stuff before inserting it into the database, if you want it though there are other JS functions for that (like escape variants that are not deprecated).

Resources