Angularjs and Rails is not working in production - ruby-on-rails

I'm getting the following error and I cannot understand why. I tried my best to change/check the origin of the error, but for me everything seems to be correct. And this error happens only in production, in development it works fine.
#error
Uncaught Error: [$injector:modulerr] Failed to instantiate module recipeApp due to:
Error: [$injector:nomod] Module 'recipeApp' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
#app.js
var mod = angular.module('recipeApp',[]);
#application.js
//= require jquery
//= require jquery_ujs
//= require pixel-admin.min
//= require app
#config/initializers/productio.rb
config.assets.compile = false
config.assets.precompile = ['*.js', '*.css']
config.assets.js_compressor = Uglifier.new(:mangle => false)
config.assets.js_compressor = :uglifier
#app/views/layout/application.html.erb
<body class="theme-default no-main-menu main-navbar-fixed" ng-app="recipeApp">
and when I check the source via firebug, I can see recipeApp in both js and html
I'm using
Rails 4.1.5
Angularjs 1.2.13
UPDATE
For routing I'm using ui.router, how ever I tried to add that as well, but still the same
#app/views/layouts/application.html.erb
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js"></script>
<script src="//angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>
in my
app/assets/javascripts/app.js
'use strict';
angular.module('recipeApp',["ui.router"]);

I also ran into this issue and found the solution here: https://teamgaslight.com/blog/4-lessons-learned-doing-angular-on-rails. Thought I'd share for anyone that runs into this issue even though this question is fairly old.
Rails in production automatically minifies variables which messes up Angular.
So in config/environments/production.rb, add this line before end:
config.assets.js_compressor = Uglifier.new(mangle: false)
Your app needs to be on Rails 4+

Uncaught Error: [$injector:modulerr] This error occurs when you not supplied ngRoute dependency in newer versions of angular.
You have to provide ngRoute dependency in your module as it's separate module in new angular versions.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular-route.min.js"></script>
var app = angular.module('recipeApp', ['ngRoute']);

Related

Uncaught ReferenceError: React is not defined on rails app

I just started to learn implementing react on rails following a tutorial. There were similar questions asked earlier and I tried those solutions, but they didn't seem to work.
I installed react-rails gem.
And added following lines to appication.js
application.js
//= require jquery
//= require jquery_ujs
//= require react
My rails version is 5.1.4 and jQuery version is 1.12.4
I am just trying to get a simple Hello React as follows.
index.html.erb
<div id="react"></div>
main.jsx
let documentReady = () => {
React.render(
<h1>Hello React</h1>,
document.getElementById('react')
);
};
$(documentReady);
At first I was getting a Uncaught TypeError: $ is not a function then I added the following line on the top of main.jsx
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
Then I started getting Uncaught ReferenceError: React is not defined
So instead of a plain Hello React I am getting all of these errors. Help would be much appreciated.

React::ServerRendering::PrerenderError in... Rails 5, React

I am using Rails 5 with react-rails gem. I want to use server-side rendering, but I see this error:
React::ServerRendering::PrerenderError in Home#index
Encountered error "# ExecJS::ProgramError: TypeError: Cannot read property 'serverRender' of undefined" when prerendering Main with {}
This is my /assets/javascripts/application.js:
//= require rails-ujs
//= require jquery
//= require react
//= require react_ujs
//= require_tree .
This is javascripts/components.jsx:
class Main extends React.Component{
render(){
return (
<h1>Hello</h1>
);
}
}
and this is the view:
<%= react_component('Main', {}, {prerender: true}) %>
Without prerender option, everything works.
I've had a similar issue and here's how I solved it
run command rails generate react:install
This will create the components folder and some required files under your javascripts/ dir.
Now, place your components.jsx in /assets/javascripts/componets directory
refresh the page.
I'm running rails 4.2.10 and haven't tested rails 5 but I'm guessing this should do the trick.
Let me know how you get on

How to force scripts to load before interpreting html in Rails Capybara JS tests

In my file dances.html.erb, my test complains:
Failures:
1) Creating dances creates a new dance with non-javascript data
Failure/Error: visit '/dances/new'
Capybara::Poltergeist::JavascriptError:
One or more errors were raised in the Javascript code on the page. If you don't care about these errors, you can ignore them by setting js_errors: false in your Poltergeist configuration (see documentation for details).
ReferenceError: Can't find variable: $
ReferenceError: Can't find variable: $
at http://127.0.0.1:33842/dances/new:81 in global code
I think the offending html code looks like
<script>
$( "#choreographer-autocomplete" ).autocomplete({
source: <%= a_to_safe_str(Choreographer.all.map &:name) %>,
autoFocus: true,
minLength: 0
});
$( "#start-type-autocomplete" ).autocomplete({
source: ["improper","Becket","Becket ccw","four face four","square dance","indecent"],
autoFocus: true,
minLength: 0
});
</script>
and the offending calls to '$' are here.
I think this means JQuery isn't loading?
If I snip them, then the next error is:
Failure/Error: JSON.parse self.figures_json
ActionView::Template::Error:
784: unexpected token at '{{toJson(figures.arr)}}'
Those handlebars are an Angular thing.
Is Angular also not loading?
Here's my Rails application.js:
//= require angular
//= require jquery
//= require bootstrap-sprockets
//= require jquery_ujs
//= require_tree .
//= require jquery-ui/autocomplete
//= require angucomplete-alt
This works fine in the Real World, just not in this test.
Is there something I need to do to get these JS libs to load before the body html is executed?
Since you are running the latest PhantomJS the most likely cause is that you have an error in one of your JS files. A big difference between the dev and test environments is that in the test environment rails concatenates all your JS files together. This means that an error in one file can prevent the rest of the JS from being processed. In dev mode they're all separate so an error in one doesn't stop the others from being processed. Check your browsers console log for errors and make sure they are fixed.

React Error (Only a ReactOwner can have refs.)

I've just installed a fresh react into my rails project with 'React-rails' and added searchkit on top of it. But I'm getting some errors with it.
Uncaught Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's render method, or you have multiple copies of React loaded.
app/assets/javascripts/components/search.js.jsx
const host = "http://demo.searchkit.co/api/movies"
const sk = new Searchkit.SearchkitManager(host, {})
var Search = React.createClass({
render: function() {
const SearchkitProvider = Searchkit.SearchkitProvider;
const Searchbox = Searchkit.SearchBox;
const Hits = Searchkit.Hits;
const NoHits = Searchkit.NoHits;
const HitsStats = Searchkit.HitsStats;
const Layout = Searchkit.Layout;
const LayoutBody = Searchkit.LayoutBody;
const LayoutResults = Searchkit.LayoutResults;
const SearchBox = Searchkit.SearchBox;
const TopBar = Searchkit.TopBar;
const SideBar = Searchkit.SideBar;
const ActionBar = Searchkit.ActionBar;
const ActionBarRow = Searchkit.ActionBarRow;
const HierarchicalMenuFilter = Searchkit.HierarchicalMenuFilter;
const RefinementListFilter = Searchkit.RefinementListFilter;
const SelectedFilters = Searchkit.SelectedFilters;
const ResetFilters = Searchkit.ResetFilters;
const MovieHitsGridItem = Searchkit.MovieHitsGridItem;
return (<div>
<SearchkitProvider searchkit={sk}>
<Layout>
<TopBar>
<SearchBox autofocus={true} searchOnChange={true} prefixQueryFields={["actors^1","type^2","languages","title^10"]}/>
</TopBar>
<LayoutBody>
<SideBar>
<HierarchicalMenuFilter fields={["type.raw", "genres.raw"]} title="Categories" id="categories"/>
<RefinementListFilter id="actors" title="Actors" field="actors.raw" operator="AND" size={10}/>
</SideBar>
<LayoutResults>
<ActionBar>
<ActionBarRow>
<HitsStats/>
</ActionBarRow>
<ActionBarRow>
<SelectedFilters/>
<ResetFilters/>
</ActionBarRow>
</ActionBar>
<Hits mod="sk-hits-grid" hitsPerPage={10} itemComponent={MovieHitsGridItem} sourceFilter={["title", "poster", "imdbId"]}/>
<NoHits/>
</LayoutResults>
</LayoutBody>
</Layout>
</SearchkitProvider>
</div>);
}
});
Fairly new with React, so not too sure why these problems are occuring?
Thanks
Ok, I just browsed through this searchkit library. Based on the fact it's a React component and you are using react-rails, I'm almost certain you are running into the issue of having two React instances at one time. react-rails drawback is the difficulty to integrate external libraries with it. It's quick to setup and start using but as soon as you want to install other react libraries, you will hit a wall.
I had this issue before and what I did was to use https://github.com/netguru/react_webpack_rails instead. If you want something abit more then have a look at https://github.com/shakacode/react_on_rails. These two options require more effort to setup but well worth it if you are serious about React and its ecosystem.
BTW: Searchkit looks great!
It seems I'm about late for the party but, just in case, someone may experience this issue again and need a more direct solution.
For your reference:
Rails 5.2.0
Ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]
React-rails (2.3.1)
I believe this could happen on different rails and ruby versions too.
As like what #kasperite said, I'm sure you are having two React instances by mistake. You are either 'require react' twice or running into the dual instances by the 'require_tree .' in the 'application.js' file.
To be more specific, you should check the following lines in the 'application.js' file:
//= require react
//= require react_ujs
//= require components
//= require_tree .
The issue is that you first load React by require react directive, then load it again using the require_tree . directive.
Ref: https://guides.rubyonrails.org/asset_pipeline.html#manifest-files-and-directives
Or direct quote from the official guide as in the above link
The require_tree directive tells Sprockets to recursively include all JavaScript files in the specified directory into the output. These paths must be specified relative to the manifest file. You can also use the require_directory directive which includes all JavaScript files only in the directory specified, without recursion.
To sort the issue, you just need to completely delete the require_tree . directive or unset it by removing the equal sign - turn this //= require_tree . to // require_tree .
Hope this help and cheers.

Rails 4 + AngularJS: App.js config and run functions don't work

I'm working with Rails 4 and AngularJS. I've got my app working. Controllers, directives, services, etc. However, my main app.js file refuses to fire the config and run functions. I've got some console.logs in there to test how far it gets. Here's the code:
angular-app/app.js
'use strict';
console.log('we see the app.js file'); // This works
var app = angular.module('bruno', [])
console.log(app) //This works
// This is where is stops working
app.config(function ($httpProvider) {
alert('config'); // Can't see this
$httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content');
})
app.run(function () {
console.log('App is running'); // Can't see this
});
Like I said, my other controllers are working just fine. The console doesn't show any errors and everything loads just as it should.
Rails application.js file:
//= require angular-app/app
//= require_tree ./angular-app/templates
//= require_tree ./angular-app/modules
//= require_tree ./angular-app/filters
//= require_tree ./angular-app/directives
//= require_tree ./angular-app/models
//= require_tree ./angular-app/services
//= require_tree ./angular-app/controllers
I've re-written this every which way I can think of, but to no avail. I'm kinda stumped. I've done it with and without the var app. Hoping this wonderful community can at least help me see something I can't.
Additional Info
I'm using gem 'angular-rails-templates'
Rails 4.2.3
AngularJS 1.3.16
If you need anything else from me just ask. Who knows, maybe by tomorrow morning I'll see things differently. :-)
As it turns out, I was mistakenly re-using the same module name inside another controller. Which was overwriting the module name in app.js. All fixed now.

Resources