Heroku + Rails + Angular = Unknown provider: eProvider <- e - ruby-on-rails

Feeling completely baffled. I know that several questions have been asked about this and I've read and reread all of them.
Angular (with ng-route) was working until a certain commit (I'll include images of the diffs of the js files). I've already changed what I would have expected to be the guilty party, shown here:
Changed this
app.run(function($rootScope, $http){
$rootScope.logout = function(){
$http({
url: 'logout',
method: 'GET'
}).success(function(data){
window.location = window.location.href;
});
};
});
to this
app.run(['$rootScope', '$http', function($rootScope, $http){
$rootScope.logout = function(){
$http({
url: 'logout',
method: 'GET'
}).success(function(data){
window.location = window.location.href;
});
};
}]);
However, even if I completely commit out the above code the error still persists, so I really don't think that's it. I've also commented out chunk by chunk of code and nothing seems to resolve this issue.
I've attached an image showing the diff in the commit file. Before this commit, angular was working fine on Heroku/production. Am I just being stupid and not seeing it?
http://imgur.com/SwsEeuH,oITUoY7,bQ8HKrj,tZF4HMS
Thanks in advance!

You get this kind of error when you use a JavaScript minifier that mangles a Angular dependency. Because Angular looks dependency up by argument name it can't find them.
I'm not sure what you are using to build your JavaScript into minified and merged files but you'll need to work out a way to do this in an Angular friendly way. I had a project recently that used the ngmin grunt plugin to minifier my JavaScript and started to get similar errors until I switched to ng-annotate.

A bit too late to this question I guess, but I stumbled accross the same problem but only while using Angular Material. All my dependencies were injected as suggested and everything worked fine before using Material.
My setup is Angular on a Rails 5 app runnning on production on Heroku. Even following the best practices on funciton annotation for Angular, injectin Angular Material will not work in production and will throw an UnknownProvider error unless you add the ngannotate-rails gem to your project.
This gem helps angular files be annotated correctly before the assets pipeline minifies the JS files and screws dependency injections up.

Related

How to integrate JqTree in Rails 6 with webpacker, tree is not a function

I am really wanting to know how to integrate jqTree as a webpacker webpack in my Rails 6 application
UPDATE:-
Using yarn add jqtree seems to have magically cleared up most of my issues however I am currently facing tree is not a function error
I am using the Ancestry gem to organise menu items and I need a drag and drop javascript tree view solution that will work nicely with the Ancestry gem. I have picked on jqTree as my desired solutions but I am happy to be persuaded to use an alternative as there seem to be a lot around but initially I would just like to be able to at least get a tree view working within Rails 6
Presumably I have to start by setting up jQuery, for which there are plenty of resources on how to do this so I guess this is more about how to get any jQuery component up and running in a Rails 6 app
I guess I'll have to start with a jsx file and import some stuff and import some css into application.scss but just what this should look like I really am unsure of
So far I have setup jQuery according to the instructions here https://www.botreetechnologies.com/blog/introducing-jquery-in-rails-6-using-webpacker
I can confirm with a simple alert that this is all hooked up and working
I have made some more progress
Instead of downloading the jqTree files, I have used yarn to install jqTree
replacing
I have downloaded the jqTree files and unpacked them to folder called jqTree inside my javascript/packs folder
with
yarn add jqtree
and now I have sorted out the require which is as it should be without the ;
So
require ;'jqTree/tree.jquery.js'
becomes
require('jqtree')
also in my javascript/packs folder I have created a sortable.js file which did contain the following
require ;'jqTree/tree.jquery.js'
jQuery(window).on('load', function () {
alert("Done"); //This works!
});
$(function() {
$('#tree1').tree({
data: data,
autoOpen: true,
dragAndDrop: true
});
})
the ; in the require statement confuses me a lot but the console error was demanding it
This now looks like this
require("jqtree");
$(function() {
alert($('#tree1').data('items'));
});
$('#tree1').tree({
data: $('#tree1').data('items'),
autoOpen: true,
dragAndDrop: true
});
With the above code I get an reference error: data is not defined
In a view I have the following code
<%=javascript_pack_tag("sortable")%>
<%= content_tag "div", id: "tree1", data: {items: #menu_items} do %>
Loading items...
<% end %>
The issue I have now is that my browser is reporting an error that tree is not a function.
In my application.css.scss I have
*= require "jqtree.css"
Which doesn't work
I have a detailed answer for this that has taken me quite sometime to put together, I will update this answer with that detail over the coming days but it starts with getting everything hooked up properly with jQuery, jQuery-ui and the componment itself which in this case is jqTree
Yarn is definitely the answer
Starting with the command line to add the relevant packages
yarn add jquery
yarn add jquery-ui
yarn add jqtree
Once the relevant yarn packages are installed I needed to make jQuery and jQuery-ui available for reasons that I am yet to fully comprehend, a simple require is not enough
Following this post https://www.botreetechnologies.com/blog/introducing-jquery-in-rails-6-using-webpacker
I setup my environment.js file in the config/webpacker folder to look like this
const { environment } = require('#rails/webpacker')
const webpack = require('webpack')
environment.plugins.prepend('Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
);
const aliasConfig = {
'jquery': 'jquery-ui-dist/external/jquery/jquery.js',
'jquery-ui': 'jquery-ui-dist/jquery-ui.js'
};
environment.config.set('resolve.alias', aliasConfig);
module.exports = environment
After restarting my server I created a simple js file called test.js in the app/javascript/packs folder which as far as I can tell is where all javascript now resides although there is still the possibility of using sprockets by putting javascript in the assets/javascript folder, I have been advised, with no explanation as to why, that it is not a good idea to mix webpacker with sprockets for serving javascript.
Webpacker does has the ability to serve stylesheets as well, however I still prefer my stylesheets to be served by sprockets in the app/assets folder and using stylesheet link tags as traditionally done in Rails apps as testing proved to be more efficient this way so mixing sprockets with webpacker in this way doesn't seem to be an issue.
I just chucked a simple alert message into the test.js file just to check that webpacker and jQuery was all hooked up properly.
So test.js looks like this
require("jquery-ui");
require("jqtree");
$(function() {
alert($('#tree1').data('items'));
});
Then to use the javascript I just included a javascript pack tag in the view I wanted to use it in like so.
in a random edit.html.erb view
<h1>Editing Menu Item</h1>
<%= render 'form', menu_item: #menu_item %>
<%= link_to 'Show', [:admin, #menu_item] %> |
<%= link_to 'Back', admin_menu_items_path %>
<%=javascript_pack_tag("test")%>
No need for paths or extensions to the file name, it just works!
I find this approach to be really neat for two reasons
1) I am not unnecessarily bloating out web pages by including page specific javascript in every single page by including it in the application.js file which gets included by default in the layout and therefore in every page.
2) I don't seem to have to worry about DOM loaded events and so far no issues with turbolinks interfering with it, although I suspect that may be more by luck than judgement and I may have to revise that thought in the future and make use of 'data-turbolinks-track': 'reload' option, but so far so good and this has not been necessary.
So now that all is hooked up and working it was time to make the jqTree component work with ancestry gem to be able to structure and organise the menu items for the site,
But up to this point it has been a simple matter of using yarn top install components and hooking up jQuery properly. I didn't use yarn initially and that led me to all sorts of problems resulting in my original question.
The rest is to follow...

inject select2 in typeScript

I have problem injecting the select2 library in my TypeScript/Angular project. I don't know what else to do to make it working, I searched for some working example of but without success.
jQuery gets loaded
select2.js gets loaded
definition file select2.d.ts is there (I also have matching version)
Module is injected like that:
public init() {
var myApp = angular.module('app', [
'ui.router',
'ngCookies',
'ui.bootstrap',
'select2'
]);
...
I get an error:
Module 'select2' is not available! You either misspelled the module name or forgot to load it.
What am I doing wrong there? Any help appreciated.
You are trying to inject Select2 into your application like an Angular module. This is throwing an error because Select2 is not an angular module, it's a jQuery component.
Angular UI provides ui-select which is an Angular native version of Select2.
So I resolved this by initializing select2 in jQuery style direct in my controller...
$('select').select2();
It is probably not very nice solution but it works. If anyone got better solution feel free to post it

AngularJS not working in release mode (minified)

I have AngularJS, and Angular directives for Bootstrap in a project, both of which have been added via Nuget.
When compilation debug="true", everything works fine, but once I change compilation debug to false, Angular stops working, and I get the following error in Chrome's console:
Error: [$injector:unpr] http://errors.angularjs.org/1.2.15/$injector/unpr?p0=nProvider%20%3C-%20n
at Error (native)
at http://localhost:10366/bundles/angular?v=Bi8OwYOhmsGdeIKC46ZQQdIHX1faTIVR48lG9QG3GBw1:1:448
at http://localhost:10366/bundles/angular?v=Bi8OwYOhmsGdeIKC46ZQQdIHX1faTIVR48lG9QG3GBw1:1:14726
at Object.i [as get] (http://localhost:10366/bundles/angular?v=Bi8OwYOhmsGdeIKC46ZQQdIHX1faTIVR48lG9QG3GBw1:1:13802)
at http://localhost:10366/bundles/angular?v=Bi8OwYOhmsGdeIKC46ZQQdIHX1faTIVR48lG9QG3GBw1:1:14801
at i (http://localhost:10366/bundles/angular?v=Bi8OwYOhmsGdeIKC46ZQQdIHX1faTIVR48lG9QG3GBw1:1:13802)
at r (http://localhost:10366/bundles/angular?v=Bi8OwYOhmsGdeIKC46ZQQdIHX1faTIVR48lG9QG3GBw1:1:14014)
at Object.instantiate (http://localhost:10366/bundles/angular?v=Bi8OwYOhmsGdeIKC46ZQQdIHX1faTIVR48lG9QG3GBw1:1:14185)
at http://localhost:10366/bundles/angular?v=Bi8OwYOhmsGdeIKC46ZQQdIHX1faTIVR48lG9QG3GBw1:1:30669
at http://localhost:10366/bundles/angular?v=Bi8OwYOhmsGdeIKC46ZQQdIHX1faTIVR48lG9QG3GBw1:1:23558 angular?v=Bi8OwYOhmsGdeIKC46ZQQdIHX1faTIVR48lG9QG3GBw1:1
(anonymous function) angular?v=Bi8OwYOhmsGdeIKC46ZQQdIHX1faTIVR48lG9QG3GBw1:1
All of my other Javascript/CSS works as expected. What could cause Angular to stop working once minified? Is this a known issue?
Thanks
ASP.NET MVC minifies javascript files when the compilation debug value is set to "false". The angular tutorial includes this note about minification:
Since Angular infers the controller's dependencies from the names of arguments to the controller's constructor function, if you were to minify the JavaScript code for [your] controller, all of its function arguments would be minified as well, and the dependency injector would not be able to identify services correctly.
The most common technique to overcome this problem is inline bracket notation, like:
phonecatApp.controller('PhoneListCtrl', ['$scope', '$http', function($scope, $http) {...}]);
This SO question explains the importance of minification safe syntax: Angularjs minify best practice

Nothing works! jquery conflict magento

I am trying to use jquery UI based transition sliders on my homepage. I tried different jquery plugins but I always get an error in the console : jQuery is not a function or some function error related to jQuery . Plugins i have tried are Lof JSliderNews 1.0,featured-content-slider, etc..
Even after following several posts on the web , iam not able to make the plugin work at all. Jquery part doesn't work. I have used carousels and other plugins with jquery.noConflict but this time nothing works!
Here's what iam doing:
jQuery.noConflict();
jQuery(document).ready(function(){
jQuery("#featured > ul").tabs({fx:{opacity: "toggle"}}).tabs("rotate", 5000, true);
});
I also tried replacing all $ with jQuery in the included scripts but that too doesn't work in magento. Please help, i need to finish the project soon
Have you tried putting all the jQuery stuff into a function and map the window.jQuery variable as an argument? Like so:
(function($){
//... do your jQuery thing here
})(jQuery);
BTW: "jQuery is not a function" might also be a hint that you forgot to load the jQuery library into your project.
Do you have "JS file merging" enabled? If yes, try to disable it, clear your cache and try again. It helped me once when I had a smiliar issue.
Regards

jQuery plugins / functions not loading after rails 3.1 upgrade

So I just recently upgraded a large project to rails 3.1. I've got the asset pipeline set up and working. However, a lot of the plugins we use and the custom jQuery functions we've written don't seem to be getting evaluated, although the source is in application.js. For example:
(function($) {
$.fn.searchable = function() {
....
}
})( jQuery );
I see this code in application.js, but anything that tries to use it gets a javascript error, undefined function. However, if I wrap the whole thing in a function definition, and call that function on document ready, then it works.
This is a really ugly workaround. Any ideas why it's not working without wrapping in a function?
Thanks.
maybe you should take a look at 'coffeescript's namescope'. e.g.
//define your js function as:
this.some_function_name() =>
alert('hello~')
//call it as:
this.some_function_name()

Resources