Trouble with script src attribute in Geddy application - javascript

I am new to Geddy and I am having trouble getting the HTML script tag to pull in external .js files. My file hierarchy looks like this:
Application
Models
Controllers
Views
ExternalJS
file.js
In one of my views, I would like to include file.js, so I have this in it's html file:
<script src='/ExternalJS/file.js'></script>
However, this doesn't actually work at pulling the file in. I suspect it has something to do with Geddy's router. As of now, going to
https://localhost/ExternalJS/file.js
results in a 404 because the router cannot match that route to a controller/action pair.
I would very much like to keep the ExternalJS folder where it is; I will need to add to it in the future. So what do I do to fix this issue? Is it a routing problem, some dumb mistake with src, or something else?

If you really want to keep that folder where it is, and not in the public directory, you'll need to write a few routes and a static file handler for it.
Your route should look something like this (this is off the top of my head, not tested)
router.get('ExternalJS/:file(.:format)').to('Main.externaljs')
Then in your main.js controller you'd need to do something like this:
this.externaljs = function (req, res, params) {
// serve up the file from disk or cache or something
}

Related

XHRs from an outside js file makes app crash

I have an api.js file where I make a couple of XHR-equests. I was using it inside a script tag inside an .ejs file, but it was getting too crowded. So after I moved everything to the api.js I'm no longer able to access its data.
Every time I try to require it from my app.js my program crashes.[nodemon] app crashed - waiting for file changes before starting... I've tried putting it inside my public folder and some other places, but it never works.
Should I export the data from api.js like I would if it was a data schema? If so, how would I do that? (something like module.exports = mongoose.model("Data", dataSchema); ? I don't have any models in api.js, it's just a couple of requests)
The .ejs file that is supposed to make use of api.js has a route like this:
app.get('/home', function(req, res){
res.render('home', { moment: moment }); //home is an .ejs file
});
The { moment: moment } is from moment.js.,.if I'm supposed to export api.js, how could I use it in this route since I'm already using moment.js. I think I can't just do
res.render('home', { moment: moment }, {api: api});
The main problem might be the app crashing since without solving this issue I won't be able to solve anything else.
Any help is appreciated. Thanks!
I'm not sure how much of the process you understand, but your ejs file is a "template" --- you pass "variables" to it and "render" it, and then express sends the html file. After it renders it, the "variables" are no longer accessible unless they're passed into a <script> tag like you might be doing. (I'm not sure how you're using moment --- or maybe you only use moment to render something server side)
Instead of trying to pass api, your html file can use the script tag, which can refer to other files like
<script src='/js/api.js'></script>
But your server (through express.js) needs to serve this file.
That is the common option, and should work for you.
You generally don't "pass" a module or library to the template engine unless you need it to render something. But if you wanted to, you can also read the api.js file as a string and "inject" it into the script tag... (I don't usually see it done this way)
<script><%= api %></script>

Inject my controllers without needing to place them all in the head tag - AngularJS

I have a structure to my angularjs app project as below:
I am aiming to have each component have its own controller and service to display portfolio information like images, videos, links etc.
The issue I am having is that the only way I am able to define each controller is by stacking them into my head tag in the index.html file. If I choose to create more pages, I am going to have to do this over and over again, meaning lots of calls, lots of load time etc.
Is there a way to inject each of these controllers into the app.module.js file, so this is the only file that needs to be loaded?
thanks in advance.
You will still have to place a script-tag into your html-file for every script-file you have. For testing/learning purposes you can just put them there by hand. But when this gets to annoying for you, consider using some kind of build tool like Gulp where you can inject them based on folder structure for example.
You can define index.js file for every folder and export this modules with gulp for bundle.js
like
module.exports =
angular.module('app.component.contact', [
]);
and assume that you need sub-folders and different directives at the contact folder like:
---contact
---list
---favorites
then:
module.exports =
angular.module('app.component.contact', [
'angularMoment',
require("./list"),
require("./favorites"),
]);
also parent of the contact like components you can do export operation like that:
module.exports =
angular.module('app.component', [
'ui.router',
require('./about'),
require('./contact'),
require('./home'),
]);
this is the simple logic of the exports from child to parent folders.

How to write the content of external .js files in a js.haml file (Ruby on Rails)

I'm using Ruby on Rails framework and I love it.
Until now I was using the show.html.haml for my views and everything worked fine. We wanted to add another option of supporting a GET request which consists the post-fix .js. For this purpose we added to the controller another parallel view named show.js.haml.
The "magic" of Rails knows to route .html post-fix requests to the first and .js post-fix requests to the latter.
The problem is when a request gets routed to the show.js.haml view, I can't find a way to write the content of external .js files. All I get is the text itself (i.e. <script src="myscripts.js" type="text/javascript"></script>) but not the actual content of the file.
I've found a solution, which surely isn't optimal (performance, robustness etc): downloading the file to the server and use the following function:
!= File.open(Rails.root.join('public' , 'js', 'jquery-1.11.2.min.js'), 'rb').read
This is the only way I found to actually write the content of a .js file.
There must be a Ruby's elegant way to write the content of external .js files into a .js.haml file.
Any help would be appreciated here.
Thanks!
I'm not sure why you need this and which case this is a good idea for, but you can try this (untested):
# show.js.haml
// some javascript
= render file: Rails.root.join('public' , 'js', 'jquery-1.11.2.min.js')
// or
"#{render file: Rails.root.join('public' , 'js', 'jquery-1.11.2.min.js')}"
Of course this will only work for local resources accessible, but hey, that's what <script src= is for.
EDIT
In case of needing to store the contents of the file in a variable as a string, you can use capture. For remote files you can use open-uri, which is part of Ruby's stdlib.
# show.js.haml
- content = capture do
- render file: Rails.root.join('public' , 'js', 'jquery-1.11.2.min.js')
# for remote files
- content = open('http://url.to/file.js').read
You can print the content later on:
= content
I think what you need is the rails asset pipeline
http://guides.rubyonrails.org/asset_pipeline.html

meteor: split code into its own file

I started with a meteor project and I noticed that code is growing rapidly.
The stuff that goes inside
if (Meteor.isClient) { .... }
is getting big now. Its all Template.box...., Template.bar...., etc code, so I think it could be placed into its own file. Is this possible ?
Yes, they should be placed in their own files and you should put your isClient code under the client directory and your isServer code under the server directory. The examples each use a single .js file because it makes it easy to read when you are only dealing with a few lines of code. However, that isn't how you should build a large project.
Typically your client code would be broken out by view or url path into files where each is responsible for a single template or a collection of a few related templates. For more ideas see the unofficial-meteor-faq.

How can I insert javascript source files into my pyramid python application and use them in my template?

I have redefined this question from the original a bit to make it more fundamental to the question at hand. The relevant parts of my filesystem are as follows.
env
tutorial
tutorial
templates
view.pt
static
myjava.js
views.py
__init__.py
Right now my view.pt template has
<script type="text/javascript" src="/static/myjava.js"></script>
Then in my __init__.py, I have
config.add_static_view(name='static',path='env/tutorial/tutorial/static')
And finally, the myjava.js file itself is very simple:
document.write("hello from the javascript file")
I am trying to follow this document: http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/assets.html
but right now none of the text is showing up. I feel like the problem lies in the paths i am giving it.
Some ideas I have had: in the config.add_static_view, the name='static' is confusing. I want users to be able to visit the url www.domain.com/firstpage, where firstpage is the result of a template that uses a javascript file resource (a file in the static folder). I am worried that these static assets are only for urls that start with www.domain.com/static/... Is this a valid concern? How can I tell the config.add_static_view function to serve the static resources for any views rendered from the view.pt template?
Edit: here is what worked:
in the template, use src="${request.static_url('tutorial:static/myjava.js')}"
then in the init.py use config.add_static_view(name='static',path='tutorial:static/')
Your javascript link, in the template, should be something like src="${request.static_url('tutorial:static/myjava.js')}"
This allows your application to be more easily relocated.
This also uses the appropriate asset specification, using the name of the package,
"tutorial", a colon, then a path relative to the location of the "tutorial" package, which in your case the package is at env/tutorial/tutorial.
Edited: I forgot about the Configurator object.
Here, you want to use a similar asset specification such as config.add_static_view('static', 'tutorial:static/').
You can make different static views for different directories as well, like: config.add_static_view('images', 'tutorial:images/')
When you do things like this, you can move the root of your application to another location, allowing you to have http://mysite.com/stable/ and http://mysite.com/devel/ having accesses to / be rewritten to /stable/.
The static views can be called from any template with code like ${request.static_url('tutorial:images/icons/favicon.ico')}
Was reading the docs here and it looks like when you call add_static_view it changes the path of the file? To quote the docs:
this means that you wish to serve the files that live in /var/www/static as sub-URLs of the /static URL prefix. Therefore, the file /var/www/static/foo.css will be returned when the user visits your application’s URL /static/foo.css.
In your case, since you're calling env/tutorial/tutorial/static "static", you might want to try src="static/Three.js"> instead

Categories