I just set up CoffeeScript (I'm also using Jade) for Meteor and it seems that my helpers (rendered and events functions too) do not work anymore.
Template.signIn.helpers
showForgotPassword: () ->
return Session.get('showForgotPassword')
The code seems to be properly generated but is embraced in an anonymous function.
I'm getting the following error in the web console:
Uncaught TypeError: Cannot call method 'helpers' of undefined (account.coffee:12)
I'm wondering whether the code is run before the page is fully loaded or if it is due to something else. I've also tried this but nothing changed (though it seems to work in this tutorial):
root = global ? window
root.Template.signIn.helpers
showForgotPassword: () ->
return Session.get('showForgotPassword')
The problem is fixed when I wrap my code with Meteor.startup (see David Weldon post).
if I put .jade and .coffee into same level folder meteor will load .coffee before .jade, then it causes no such template. To prevent this, you can prefix jade files with _.
Thanks for the great pointer #Julien.
I run into this issue about a few hours back and have been breaking my head since.
What I did instead of the _ approach, was to name my jade files as .html.jade and my coffeescript files as .js.coffee
That way the jade files are loaded before the coffee files and everything works.
The advantage to the _ approach is that related jade and coffee files are together.
Hope this helps.
I think this is solved in meteor-jade v0.2.2
Related
PROBLEM DESCRIPTION.
I'm trying to follow https://github.com/lucascosta/facebook-js-ads-sdk to install the Javascript SDK for Facebook. Before anyone objects, I am absolutely aware of the compact version (https://developers.facebook.com/docs/javascript/quickstart), but that API is absolutely useless to me. I need the one produced by Lucas Costa, in order to be able to make changes to my ads account, which the recommended script by Facebook does not enable.
As usual installation instructions (see github.com/lucascosta/facebook-js-ads-sdk) are horribly predicated on mysterious conditions, that are unbeknown to me. I cannot get the SDK to work and would like someone to tell me explicitly what to do. The crux of the problem is the paradoxical situation: I am supposed to use a require('...') command (where??) to include the SDK (where is this supposed to be saved??) and yet require cannot be used on folders, but on scripts. Maybe somewhere there is a require.config file, I'm supposed to set up, but I have no idea, as, like I said, the instructions completely bypass any mention of the necessary starting conditions.
Here is what I have done so far. My folder-structure looks like this (I don't even know if this is right, as no-one explains it anywhere!):
[Serverroot]
— [folder with my website]
– facebook-ads-sdk (the folder one gets by downloading)
– css — pagestyles.css
– js — lib
require.js
— app
( some header scripts )
– img
( some images )
index.php
In index.php I have a block of html followed by some javascript. It is here, that I try to insert the setup / example code from . The browser cannot even get past the line const adsSdk = require('facebook-ads-sdk');. I have tried a number of things: require('./facebook-ads-sdk');, moving all this to the folder ./js/app in a script main.js and then writing in my html in index.php where main and require are located. Setting up a require.config (or requirejs.config) replacing require by requirejs, etc. and including the appropriate scripts in the <head> part of index.php. Nothing helps. Here are the errors: first with const adsSdk = require('facebook-ads-sdk'); I get
Error: Module name "facebook-ads-sdk" has not been loaded yet for context: _. Use require([])
Okay. How do I ‘load the Module for the context _’?? Reading requirejs.org/docs/start.html is of no help here. I tried require([], function() {require('facebook-ads-sdk')}); Same error. I tried require(['facebook-ads-sdk']);
I tried using the following commands in my script in index.php:
require.config({
shim: {
'facebook': {
exports: 'adsSdk',
},
},
paths: {
'sdk': './facebook-ads-sdk',
}
});
var adsSdk = require(['sdk']);
Then I get the error
Failed to load resource: http:// .... /facebook-ads-sdk.js the server responded with a status of 404 (Not Found)
Ie, the browser thinks I'm trying to include a script facebook-ads-sdk.js, but I’m supposed to(???) ‘require’ the entire folder! What is going on? Can someone please give me thorough instructions about the necessary folder structure and command, in order to get this SDK working?
Why is this so infuriatingly vaguely described online? Is there some kind of mysterious way of installing SDKs, about which ‘everyone’ knows, but never mentions?
UPDATE: SOLUTION. For any future google-searches for this same problem: via the following simple methods, one can install & embed the Javascript-FB-Ads-SDK:
install via npm install --save facebook-ads-sdk a copy of the npm modul Lucas Costa’s facebook-ads SDK.
Copy this folder to your website’s architecture (actually you possibly just need one subfolder / file).
in your HTML include the script (via <script type='text/javascript' src='...'></script>) with the src pointing to the file in the facebook-ads-sdk folder: /dist/iife.js.
In your page’s script, you now have access to then API via the global variable fb.
alternatively to 3:
3’. in your HTML headers make sure to include the require.js script via a <script>-tag. Then in your website’s javascript apply the following commands anywhere:
require.config({
paths: {
'sdk': './[FOLDERNAME OF SDK]/dist/iife',
}
});
require(['sdk']);
Credit and special thanks goes to #SLaks and #KhauriMcClain (I would give you up-points if I could) for this solution.
The instructions are assuming that you're using a bundling system like Webpack or Browserify.
If you are, the instructions "just work"; you can require() it and everything will work fine.
If you're building a non-trivial codebase, you really should use such a system.
If you aren't, you can reference iife.js in a <script> tag and that will create global variables.
You need to change the way you are using require.
You cannot use the synchronous require method to load dependencies if they have not been loaded before. Hence const adsSdk = require('facebook-ads-sdk'); will not work. You will need to use the form require(['name-of-script'], callback).
Require does not allow you to load an entire folder. You have to find the exact script you are trying to work with so var adsSdk = require(['sdk']); will not work.
Ultimately your code should look something like:
require(['some-facebook-script'], function(someFacebookScript) {
// Do some work here
});
The parameter passed to the callback function will be the loaded module you are trying to consume. When using the asynchronous version (as I just demonstrated) the return from require is not useful.
I started to use Coffeescript on my Meteor app and while in packages everything works great, I've encountered some issues while converting my js files template functions into .coffee.
Even though the coffeescript seems to be correct when I compile it, my helpers and events don't seem to be triggered when I render the web page. I don't even get an error on the web console.
I searched but couldn't find anything but this thread.
I use Jade, Coffeescript and my .coffee and .jade files are located in the same folder, giving something like :
client/templates/myTemplate/myTemplate.jade
client/templates/myTemplate/myTemplate.coffee
I tried the _ method, to rename my files to .html.jade and js.coffee but nothing worked so far. If I put the computed javascript in a myTemplate.js file, everything works.
Any thoughts?
Below is a sample of the code:
Template.loginButton.helpers
statusText: () ->
console.log 'anybody there?'
if Meteor.user() then "Déconnexion" else "Connexion"
Coffeescript is sensitive to indentation. The site js2.coffee is very helpful if you are new to using coffeescript. Paste your code in there and the following JS is output, showing that you have effectively generated a no-op:
Template.loginButton.helpers;
({
statusText: function() {
console.log('anybody there?');
if (Meteor.user()) {
return "Déconnexion";
} else {
return "Connexion";
}
}
});
On the other hand, with the correct indentation
Template.loginButton.helpers
statusText: () ->
console.log 'anybody there?'
if Meteor.user() then "Déconnexion" else "Connexion"
you get
Template.loginButton.helpers({
statusText: function() {
console.log('anybody there?');
if (Meteor.user()) {
return "Déconnexion";
} else {
return "Connexion";
}
}
});
UPDATE: Since that wasn't the problem, note that if you're using both a third-party templating system (jade) and a third-party JS transpiler (coffeescript), you'll need to load the templating first before the JS to make sure that you can access the templates from your code. So either in your .meteor/packages (for an app), or in package.js (for a package), make sure jade comes before coffeescript.
P.S. I have been a long time coffee user, but I'm switching over to ES6 as it has most of the important features of coffee without as much chance to shoot yourself in the foot. Also, it's hard to work with people that don't know coffee.
Thanks to Andrew, I finally found out the issue.
Turns out I installed Coffeescript through npm, which did not cause any trouble while the .coffee were in a package since they are up in the loading order in any situations.
But when it comes to templates and helpers, order then mattered and I guess the npm coffeescript library was compiled and executed before the .jade template could exist, causing my helpers to not be attached to any template.
Finally
meteor add coffeescript
and making sure jade was placed before coffeescript in .meteor/packages did the trick.
I'm getting a strange behavior with RequireJS on IE.
Sometimes (this is purely random) the generated js file reference appears with the ID, not the file name.
I explain,
on the paths I have:
jqGridz: "jquery.jqGrid/js/jquery.jqGrid.min"
on the shim I have:
"jqGridz": ["jqueryUi", "jqGrid_i18n_en"]
Sometimes the end result is correctly resolved to:
/public/javascripts/jquery.jqGrid/js/jquery.jqGrid.min.js
But other times (a lot of times) it gets rendered as:
/public/javascripts/jqGridz.js
So instead of the path for jqGrid I'm getting the ID of the path.
This only happens on IE and I don't know why.
I'm using RequireJS v2.0.6
Thanks in advance!
Figured out...
I picked up this project with RequireJS already implemented but it's a mess.
So what's happening is that whenever RequireJS can't load the resource (for me was a 404) it put the key name instead of the file path.
So basically if you have have this problem have a look at the resources loading list in Firebug or Fiddler and search for errors :)
Cheers!
I am using Handlebars.js with precompiled templates. I have the following code (using JQuery in the first line):
$('#'+id).append('<script src="'+widgetContext.templateDir+
template+'.tmpl">');
console.log(Handlebars);
console.log(Handlebars.templates);
var html = Handlebars.templates[template](data);
I get the following at the console:
The 'widget_container' template file definitely exists in the location specified. I've also tried with both the standard handelbars.js and handelbars.runtime.js.
Any idea what is going on here or how to fix the error?
Update: it appears to work if the HTML is on the same domain as the javascript file and templates but not if it isn't, so something to do with the same origin policy? I'm trying the handlebars require.js plugin here https://github.com/SlexAxton/require-handlebars-plugin but having problems getting it working.
I solved this using:
The text plugin for require.js and loading the handlebars templates as text files
The optimizeAllPluginResources build option for r.js
Getting a very recently updated version of require.js/r.js which fixed a bug with the
optimizeAllPluginResources build option
A rather horrible use of eval to run the template file code - would still be nice to avoid this
Still not quite sure exactly what was going on with the undefined Handlebars.templates though.
I have views in my application that reference my application.js file which contains functions I use throughout my application.
I just installed the Rails 3.1 release candidate after having used the edge version of 3.1. Until I installed the RC I wasn't having any problems but now I'm getting this error:
ReferenceError: Can't find variable: indicator_tag
indicator_tag is a function I defined in application.js.
The only difference I notice in the javascript file is that now all my functions are wrapped in:
(function() { ... }).call(this);
I understand this is for variable scoping? But could it be preventing my pages from using those variables? And before anyone asks, I've made sure the javascript paths are correct in my include tags.
By default, every CoffeeScript file is compiled down into a closure. You cannot interact with functions from a different file, unless you export them to a global variable. I'd recommend doing something like this:
On top of every coffeescript file, add a line like
window.Application ||= {}
This will ensure that there's a global named Application present at all times.
Now, for every function that you'll have the need to call from another file, define them as
Application.indicator_tag = (el) ->
...
and call them using
Application.indicator_tag(params)
Dogbert's solution is a great way to go if you have a very sophisticated JS back-end. However, there's a much simpler solution if you only have a handful of functions you're working with. Just add them directly to the window object, like this:
window.indicator_tag = (el) ->
...
Then you can use your functions from anywhere without having to wrap them up in another object.