Uncaught ReferenceError: require is not defined using AngularJS, Rails 4 and Browserify - ruby-on-rails

I am using AngularJS and Rails, and followed http://start.jcolemorrison.com/setting-up-an-angularjs-and-rails-4-1-project/ and several other tutorials to get a very simple "Hello World" example up and running on my desktop. The problem is, when I deploy it to a server, none of my code based on Angular works anymore. Instead, I get a Uncaught ReferenceError: require is not defined error in my console.
I realized that part of my problem is that the browser doesn't know what to do with the 'require' function calls, which makes sense so I installed Browserify using browserify-rails. However, it still does not work on the server like I would expect and I get the same error.
Link to the live site: Link
Here's my application.html.erb (simplified):
<!DOCTYPE html>
<html>
<head>
<base href="/" />
<title>ShibaInu</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => false %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => false %>
<%= csrf_meta_tags %>
</head>
<body ng-app="shibaInu">
<div class="container">1 + 2 = {{ 1 + 2 }}</div>
<div class="container">
<%= yield %>
</div>
</body>
</html>
index.html.erb:
<div ng-view=""></div>
home.html.erb (rendered inside the container):
<h1>The Home View!</h1>
<ul>
<li ng-repeat="thing in things">
{{thing}}
</li>
</ul>
home.js:
angular.module('shibaInu')
.controller('HomeCtrl', function ($scope) {
$scope.things = ['Angular', 'Rails 4.1', 'Working', 'Together!!'];
});
app.js:
angular
.module('shibaInu', [
'ngRoute',
'templates'
]).config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'home.html',
controller: 'HomeCtrl'
});
$locationProvider.html5Mode(true);
});
application.js
//= require jquery
//= require jquery_ujs
//= require angular
//= require angular-route
//= require angular-resource
//= require angular-rails-templates
//= require bootstrap-sprockets
//= require ng-app/app.js
//= require_tree ../templates
//= require_tree .

I was doing several things wrong, but I'll try to summarize:
I am minifying JS on my server deployment like a good boy, but I was not writing minification-safe JS. See below for my fixed JS.
This wasn't specified in my original post, but I was not using the angularjs-rails gem like I thought I was. I added this to my project.
Related to 2 above, in my initial post I had used bower to install angularjs like the documentation recommends. For my solution, I took this out because it was just making things messy for my purposes.
New home.js:
angular.module('shibaInu')
.controller('HomeCtrl', ['$scope', function ($scope) {
$scope.things = ['Angular', 'Rails 4.1', 'Working', 'Together!!'];
}]);
New app.js:
angular
.module('shibaInu', [
'ngRoute',
'templates'
]).config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'home.html',
controller: 'HomeCtrl'
});
$locationProvider.html5Mode(true);
}]);

Related

Excel Add In - Javascript only working after reload

I am developing an Excel Add-In using the Office-JS Library.
When some pages are loaded, the JS is not loaded properly.
The Javascript only works after reloading the page.
I disabled turbolink as suggested in another question.
But my problem still appears.
My office_connect.js contains the following:
//= require jquery3
//= require jquery_ujs
//= require_self
//= require select2-full
//= require select2_locale_de
And the head of my layout file:
<%= yield :head_top %>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<%= stylesheet_link_tag "office_connect"%>
<%= javascript_include_tag "office_connect_app"%>
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script>
<%= javascript_include_tag "oc_function"%>
<%= javascript_include_tag "office_excel"%>
<title><%=t('layouts.head.text_immodatacockpit')%></title>
<%= csrf_meta_tag %>
<%= yield :head %>
The oc_function file starts Office JS:
// The initialize function must be run each time a new page is loaded.
(function () {
Office.initialize = function (reason) {
// If you need to initialize something you can do so here.
};
})();
A shortened version of my excel.js:
(function () {
"use strict";
var cellToHighlight;
var messageBanner;
var config;
var sheetData;
let housing_output_template_new;
let housing_output_template_edit;
// The initialize function must be run each time a new page is loaded.
Office.initialize = function (reason) {
$(document).ready(function () {
$(".spinner").hide();
// If not using Excel 2016, use fallback logic.
if (!Office.context.requirements.isSetSupported('ExcelApi', '1.1')) {
$('#subtitle').text("Opps!");
$("#template-description").text("Sorry, this sample requires Word 2016 or later. The button will not open a dialog.");
$('#button-text').text("Button");
$('#button-desc').text("Button that opens dialog only on Word 2016 or later.");
return;
}
$("#select1").select2({placeholder: 'Please choose' , language:'<%= I18n.locale %>',dropdownAutoWidth:true});
$(".select4").select2({placeholder: 'Please choose' , language:'<%= I18n.locale %>',dropdownAutoWidth:true});
});
}
})();
I think it has something to do with the order I load the JS libraries.
Could you point me in the direction of what I am missing?
It looks like you are assigning Office.initialize in two places. If these calls are on two different pages, then that's OK. But you shouldn't be doing this twice on the same page.

Foundation 6 top-bar dropdown won't close

I added a dropdown menu to my top-bar, all the submenus appear when I hover the mouse over it.
The problem is after starting the server then when I click any link in my application then the whole submenu aligns vertically in the topbar and won't go away. When I refresh the page with F5 then the submenu items disappear but when I click any other link then they appear again in fixed position, aligned under the dropdown menu link.
Before hover:
On hover:
After clicking whatever link in the app:
To be sure I'm not messing it up myself while describing the front end, I copy-pasted example from Foundation page directly:
.top-bar
.top-bar-left
ul.dropdown.menu data-dropdown-menu=''
li.menu-text Site Title
li
a href="#" One
ul.menu.vertical
li
a href="#" One
li
a href="#" Two
li
a href="#" Three
li
a href="#" Two
li
a href="#" Three
I'm using slim for syntax and:
foundation-rails 6.4.3.0
rails 5.1.6
ruby 2.5.1
I checked the javascript console with broswer inspection tools and no errors there (also no errors in server log). I even tested with removing turbolinks in main-layout head but of course it didn't affect. I'm running out of thoughts how to debug further.
My application layout (the top-bar resides in _navbar partial which gets rendered in body):
doctype html
html lang= I18n.locale.to_s
head
meta charset='utf-8'
meta name='viewport' content='width=device-width, initial-scale=1.0'
title == content_for?(:title) ? yield(:title) : t('general.home')
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
= include_gon(init: true)
= javascript_include_tag 'application'
= javascript_include_tag 'https://www.gstatic.com/charts/loader.js'
= csrf_meta_tag
= favicon_link_tag 'favicon.ico'
body
.main
= render 'layouts/navbar'
= render 'layouts/title', title: #title
= render 'layouts/messages'
= yield
And my application javascript (if somehow the order of reloading libaries should matter):
//= require jquery
//= require rails-ujs
//= require turbolinks
//= require rails.validations
//= require rails.validations.simple_form
//= require foundation
//= require chartkick
//= require ckeditor/init
//= require_tree .
$(function(){ $(document).foundation() })
Similar problem described here, but the solution isn't working for me: https://foundation.zurb.com/forum/posts/38667-foundation-62-topbar-dropdown-issue
I'ts a turbolinks issue: inside your application javascript you should load foundation on turbolinks:load like this:
$(document).on('turbolinks:load', function() {
$(function(){ $(document).foundation() })
})
Have a look at here for more information.

Angular ui-router templates are not loading, Rails backend

I'm following along with the Angular/Rails tutorial at Thinkster and I've run into an issue which seems to be most likely be Angular-related. Everything works just fine until I get to the Angular Routing section. Simply put, the inline templates within the <script> tags do not load in the <ui-view></ui-view> element. I originally thought this may be due to having opened the page locally as a file rather than having it loaded from a server, but the same problem persists even after integrating Rails (using an older version of Sprockets, as pointed out in this similar but unrelated issue).
When I load the index page in either the browser as a file or as a URL when running the Rails server, I've inspected the HTML and, sure enough, the only thing it shows in the code are the divs and an empty <ui-view> element, indicating something just isn't adding up correctly. I've tried various things, including:
Using the newest version of ui-router (0.2.15 at this writing) rather than the version in the tutorial
Using <div ui-view></div> instead of <ui-view></ui-view>
Changing the value of 'url' in the home state to 'index.html', including using the full path to the file (file:///...)
Putting the contents of the inline <script> templates into their own files (without the <script> tags, of course) and specifying the 'templateUrl' field using both relative and full paths
Trying both Chrome and Firefox just to be extra certain
None of these things have worked, even when accessing http://localhost:3000/#/home when the Rails server is running after having integrated Angular into the asset pipeline in the Integrating the Front-end with the Asset Pipeline section of the tutorial. Indeed, the route loads but does not show anything more than a completely blank page with a lonesome and empty <ui-view> element when inspecting the HTML using Chrome's dev tools.
Given that the issue seems to occur even before the Rails portion, it does seem like something to do with Angular itself, but I've got no clue what's going on, especially since I've followed along to the letter.
I'm using Bower to manage the Angular dependencies and the HTML does show that the Angular javascript files in both the app/assets/javascripts directory and in the vendor/assets/bower_components directory are being loaded properly in the <head> section, so everything seems to be okay on the asset pipeline integration.
Versios I'm using:
Rails: 4.2.3
Ruby: 2.2.1p85
Angular: 1.4.3
ui-router: 0.2.15
The code I've got for the major moving parts is below:
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Test App</title>
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_include_tag 'application' %>
<%= csrf_meta_tags %>
</head>
<body ng-app="testApp">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
</div>
</div>
</body>
</html>
app/assets/javascripts/app.js
angular.module('testApp', ['ui.router', 'templates']).config(['$stateProvider', '$urlRouteProvider', function($stateProvider, $urlRouteProvider) {
$stateProvider
.state('home', {
'url': '/home',
'templateUrl': 'home/_home.html',
'controller': 'MainCtrl'
})
.state('posts', {
'url': '/posts/{id}',
'templateUrl': 'posts/_posts.html',
'controller': 'PostsCtrl'
});
$urlRouteProvider.otherwise('home');
}]);
app/assets/javascripts/application.js
//= require angular
//= require angular-rails-templates
//= require angular-ui-router
//= require_tree .
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
respond_to :json
def angular
render 'layouts/application'
end
end
config/routes.rb
Rails.application.routes.draw do
root to: 'application#angular'
end
app/assets/javascripts/home/mainCtrl.js
angular.module('testApp').controller('MainCtrl', ['$scope', 'posts', function($scope, posts) {
$scope.posts = posts.posts;
$scope.addPost = function() {
if (!$scope.title || $scope.title === "")
return;
$scope.posts.push({
'title': $scope.title,
'link': $scope.link,
'upvotes': 0,
'comments': [
{'author': 'Some Person', 'body': 'This is a comment.', 'upvotes': 0},
{'author': 'Another Person', 'body': 'This is also a comment.', 'upvotes': 0}
]
});
$scope.title = "";
$scope.link = "";
};
$scope.incrementUpvotes = function(post) {
post.upvotes++;
};
}]);
app/assets/javascripts/posts/postsCtrl.js
angular.module('testApp').controller('PostsCtrl', ['$scope', '$stateParams', 'posts', function($scope, $stateParams, posts) {
$scope.post = posts.posts[$stateParams.id];
$scope.addComment = function() {
if($scope.body === '')
return;
$scope.post.comments.push({
'body': $scope.body,
'author': 'user',
'upvotes': 0
});
$scope.body = '';
};
}]);
app/assets/javascripts/posts/posts.js
angular.module('testApp').factory('posts', ['$http', function($http) {
var o = {
'posts': []
};
o.getAll = function() {
return $http.get('/posts.json').success(function(data) {
angular.copy(data, o.posts);
});
};
return o;
}]);
If any other code is required to help uncover the problem, please let me know and I'll supply anything requested.
it seems that the angular-ui-router is incompatible with the new Rails sprockets. To fix this, add this earlier version of sprockets to your gemfile:
gem 'sprockets', '2.12.3'
And then run bundle update sprockets.
This was answered a few times in other similar questions, like the one below:
Angular Rails Templates just not working
$urlRouteProvider in my code should've been $urlRouterProvider. Be sure to double-check everything, folks, and make good use of the console!

collection_select with select2 and bootstrap: undefined is not a function

In a Rails 4.1 app, I have a collection select that is loaded from a hash. I would like to use the select2 boostrap styling, but it doesn't seem to be working.
I have included the select2-rails gem, and updated application.js and application.css as per the instructions.
gem 'select2-rails'
//= require select2
*= require select2
*= require select2-bootstrap
The collection_select is loaded from a constant on the model. I don't think this is especially relevant to the issue, but added it here in case it helps someone.
FLASHCARD_TYPE = {"verb" => "Verb Conjugation",
"name" => "Word",
"number" => "Number",
"quiz" => "Quiz"}
Rails view
<div class="form-group">
<%= f.label :card_type, :class => "col-sm-2 control-label" %>
<div class="col-sm-2">
<%= f.collection_select(:card_type, Flashcard::FLASHCARD_TYPE, :first, :last) %>
</div>
</div>
app/assets/javascripts/application.js
$(document).ready(function(){
$("#flashcard_card_type").select2();
});
The rendered html shows the select2 javascript, and the select shows as:
<div class="form-group">
<label class="col-sm-2 control-label" for="flashcard_card_type">Card type</label>
<div class="col-sm-2">
<select id="flashcard_card_type" name="flashcard[card_type]">
<option value="verb">Verb Conjugation</option>
<option value="name">Word</option>
<option value="number">Number</option>
<option value="quiz">Quiz</option></select>
</div>
</div>
How can this to work properly?
In fact I would also like the option to have a site-wide default for all selects via class, then the ability to override styling by individual id.
I thought this would work as site-wide for all selects, but it also does nothing.
$(document).ready(function(){
$("select").select2();
});
EDIT
As recommended by #San I checked the Javascript console, and got
Uncaught TypeError: undefined is not a function
This the code it failed on
$(document).ready(function(){
$("#flashcard_card_type").select2();
});
EDIT 2
Full application.js file
//= require jquery
//= require jquery_ujs
//= require bootstrap-sprockets
//= require bootstrap-markdown
//= require select2
//= require_tree .
$(document).ready(function(){
$("#flashcard_card_type").select2();
});
EDIT 3
jQuery is finding the element OK
$(document).ready(function(){
debugger;
console.log($("#flashcard_card_type"))
$("#flashcard_card_type").select2();
});
log
[select#flashcard_card_type, context: document, selector: "#flashcard_card_type", jquery: "1.11.1", constructor: function, toArray: function…]
0: select#flashcard_card_type
context: document
length: 1
selector: "#flashcard_card_type"
__proto__: Object[0]
EDIT - What I have tried
removed turbolinks
added the javascript to the page
deleted cache, restarted rails
What I have found
jQuery can find the tag
The select2 library is loaded via the network tab in the js debugger
Any ideas?
Just wondering. Did you run bundle install after adding the gem to the Gemfile?
If you did, the last thing to check is to make sure select2 JavaScript file is loading before your block to use it. Verify that by doing view source on the page and make sure select2.js is listed before application.js file (assuming you are in dev mode).

Bootstrap-Datepicker not working

I'm trying to use a bootstrap-datepicker for my RoR application, specifically this one.
I've downloaded the js file and put it in the assets/javascripts folder
then I made a single view in order to make it work in the simplest way possible, this is what it has
<input type="text" value="02-16-2012" class="datepicker">
<script>
$('.datepicker').datepicker({
format: 'mm-dd-yyyy'
});
</script>
It naturally shows the textfield with "02-16-2012" in it, but it doesn't make the little calendar to pop up at click. Any ideas what I'm missing?
Here's what my application.js file has:
//= require jquery
//= require jquery_ujs
//= require twitter/bootstrap
And what my application.css flie has:
*= require_self
*= require_tree .
*= require bootstrap_and_overrides
*= require bootstrap
The console displays 2 errors
Failed to load resource: the server responded with a status of 404 (Not Found) http://127.0.0.1:3000/assets/default.css
Uncaught TypeError: Object [object Object] has no method 'datepicker' test:113
Also the output for console.log($('.datepicker')) is:
[input.datepicker, prevObject: jQuery.fn.jQuery.init[1], context: document, selector: ".datepicker", jquery: "1.9.1", constructor: function…]
Your jQuery selector is missing a dot (.), you need to add a dot to capture all the elements having datepicker as class:
<input type="text" value="02-16-2012" class="datepicker">
<script>
$('.datepicker').datepicker({
format: 'mm-dd-yyyy'
});
</script>
You may want to "secure" your datepicker deployment on only inputs having datepicker class:
$('input.datepicker').datepicker({ # match every input having 'datepicker' class
format: 'mm-dd-yyyy'
});
Maybe try the following:
$(document).ready(function() {
$('.datepicker').datepicker();
})
Try adding the datepicker css.
The required markup from the documentation (specifically, you need to add the span.add-on and i.icon-th):
<div class="input-append date datepicker" data-date="12-02-2012"
data-date-format="dd-mm-yyyy">
<input class="span2" size="16" type="text" value="12-02-2012">
<span class="add-on"><i class="icon-th"></i></span>
</div>
To get the CSS and Javascript properly packed in rails assets pipeline, I recommend you to use this gem: https://github.com/lubieniebieski/bootstrap-datetimepicker-rails

Resources