AngularJS Error: [$controller:ctrlreg] Controller is not registered - ruby-on-rails

StackOverflow Peeps,
I'm having a bit of an issue with the error referenced in the title. I've scoured AngularJS documentation, previously written code, and existing StackOverflow question/answers, all to no avail. To start, here is a previously written Angular controller that works correctly:
Correct, functioning controller
And here is the malfunctioning controller:
Malfunctioning controller
What is particularly frustrating is that I quite literally copied my code from the functioning Angular controller ("focus_groups_ctrl") into my new controller ("agencies_ctrl"), and simply updated the variable/argument names to reflect this. What am I missing here? The JSON data being rendered in api/v1/agencies is working correctly, and my HTML page is being correctly "wrapped" in ng-app and ng-controller attributes. Please let me know, and feel free to ask away! Thanks!
Here is the malfunctioning code:
/* global angular */
(function() {
"use strict";
angular.module("app", ["ngAnimate"]).controller("agencies_Ctrl", function($scope, $http) {
$scope.setup = function() {
$http.get('/api/v1/agencies' + window.location.search).then(function(response) {
$scope.agenciesOffset = 0;
$scope.agenciesCount = 5;
$scope.agencies = response.data;
console.log($scope.agencies);
});
};
var i = 5;
$scope.nextLoad = function() {
$scope.agenciesOffset = i;
i += 5;
};
});
}());
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
And here is the functioning code:
/* global angular */
(function() {
"use strict";
angular.module("app", ["ngAnimate"]).controller("focus_groups_Ctrl", function($scope, $http) {
$scope.setup = function() {
$http.get('/api/v1/focus-groups' + window.location.search).then(function(response) {
$scope.focusGroupOffset = 0;
$scope.focusGroupCount = 5;
$scope.focusGroups = response.data;
console.log($scope.focusGroups);
});
};
var i = 5;
$scope.nextLoad = function() {
$scope.focusGroupOffset = i;
i += 5;
};
});
}());
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

An unknown controller error can also be caused by accidentally redefining a module using the angular.module API, as shown in the following example.
angular.module("app", ["ngAnimate"]).controller("agencies_Ctrl", fn1);
angular.module("app", ["ngAnimate"]).controller("focus_groups_Ctrl", fn2);
To fix this problem, make sure you only define each module with the angular.module(name, [requires]) syntax once across your entire project. Retrieve it for subsequent use with angular.module(name). The fixed example is shown below.
angular.module("app", ["ngAnimate"]);
angular.module("app").controller("agencies_Ctrl", fn1);
angular.module("app").controller("focus_groups_Ctrl", fn2);

Related

Adwords conversion tracking on link clicks that open in a new tab

I want to track the conversion for links in adwords; For this i have the classic code that looks like this(don't worry about values for conversion_id and conversion_label):
<!-- Google Code for Joc Sloturi2 Conversion Page
In your html page, add the snippet and call
goog_report_conversion when someone clicks on the
chosen link or button. -->
<script type="text/javascript">
/* <![CDATA[ */
goog_snippet_vars = function() {
var w = window;
w.google_conversion_id = xxxxxxx;
w.google_conversion_label = "dsadsadsadsadadsa";
w.google_conversion_value = dsadasda;
w.google_conversion_currency = "RON";
w.google_remarketing_only = false;
}
// DO NOT CHANGE THE CODE BELOW.
goog_report_conversion = function(url) {
goog_snippet_vars();
window.google_conversion_format = "3";
var opt = new Object();
opt.onload_callback = function() {
if (typeof(url) != 'undefined') {
window.location = url;
window.open(url, '_blank')
}
}
var conv_handler = window['google_trackConversion'];
if (typeof(conv_handler) == 'function') {
conv_handler(opt);
}
}
/* ]]> */
</script>
<script type="text/javascript"
src="//www.googleadservices.com/pagead/conversion_async.js">
</script>
After that the outbound links are looking like this
Link text whatever
My problem with this is that when I click on the link it opens the link in a new tab and also in the same tab (basically it opens the link twice); Is there a way to only open the link in a new tab in the browser and also track the conversion for it?
I know this is a bit old, but I found a solution. Remove
window.location = url;

Turbolinks and 3d party plugins issue?

I have website
http://www.optimapo.ru/
and I have some 3d party scripts installed:
live chat (https://www.jivochat.com/) and yandex analitics.
But because of turbolinks they don't work properly.
For example live chat appears only on main page. But when we go to another page which is loaded using turbolinks it dissapears.
I include scripts in my code before closing body tag
<!-- BEGIN JIVOSITE CODE {literal} -->
<script type='text/javascript'>
(function(){ var widget_id = '2qq06akKwZ';var d=document;var w=window;function l(){
var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true; s.src = '//code.jivosite.com/script/widget/'+widget_id; var ss = document.getElementsByTagName('script')[0]; ss.parentNode.insertBefore(s, ss);}if(d.readyState=='complete'){l();}else{if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();</script>
<!-- {/literal} END JIVOSITE CODE -->
<!-- Yandex.Metrika counter --> <script type="text/javascript"> (function (d, w, c) { (w[c] = w[c] || []).push(function() { try { w.yaCounter39034390 = new Ya.Metrika({ id:39034390, clickmap:true, trackLinks:true, accurateTrackBounce:true, webvisor:true, trackHash:true, ut:"noindex" }); } catch(e) { } }); var n = d.getElementsByTagName("script")[0], s = d.createElement("script"), f = function () { n.parentNode.insertBefore(s, n); }; s.type = "text/javascript"; s.async = true; s.src = "https://mc.yandex.ru/metrika/watch.js"; if (w.opera == "[object Opera]") { d.addEventListener("DOMContentLoaded", f, false); } else { f(); } })(document, window, "yandex_metrika_callbacks"); </script> <noscript><div><img src="https://mc.yandex.ru/watch/39034390?ut=noindex" style="position:absolute; left:-9999px;" alt="" /></div></noscript> <!-- /Yandex.Metrika counter -->
</body>
So what do I do to make scripts work with turbolinks?
I don't think that this is strictly possible with how the snippet you include is implemented. Let's look at it, I put it over multiple lines to make it easier to read, but this is all in there:
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = '//code.jivosite.com/script/widget/'+widget_id;
var ss = document.getElementsByTagName('script')[0];
ss.parentNode.insertBefore(s, ss);
If you look at turbolinks compatibility, one of the issues it reports are self loading scripts appending to head: http://reed.github.io/turbolinks-compatibility/
I don't know where document.getElementsByTagName('script')[0] lives on your page, but there's good chance it's in the head, since it's the first script on the page. Can you change to snippet to insert at the end of the body instead?
I've managed to find a solution that actually works in Turbolinks 5. I've added this piece of code s.setAttribute('data-turbolinks-track', 'reload'); in between existing code, like this:
s.type = 'text/javascript'; s.setAttribute('data-turbolinks-track', 'reload'); s.async = true;
Side note: I've also submitted a PR with this solution to Turbolinks Compatability repository
Turbolinks overrides the normal page loading process and sometimes scripts needs refresh. Here is the rails guide for using tubolinks on page load. It is coffescript. Here is javascript equivalent :
$(document).on("turbolinks:load", function() {
// your code here
});
Below code snippet works for me.
var ready;
ready = function() {
...your code ...
};
$(document).ready(ready);
$(document).on('page:load', ready);
You can try using this gem in your application:
gem 'jquery-turbolinks'
Follow the set-up instructions here.
Place your Metrika and JivoSite scripts onto the bottom of the page. You do not need to require them explicitly.
This works for me, just change
jivo_id = 'ID-MY-ACCOUNT';
Source: https://gist.github.com/Brunomm/5c227e6c254332290812
jQuery(document).on('page:load', runChat);
jQuery(document).ready(function($) {runChat();});
// Chat online jivo
function runChat(){
$('#jivo-iframe-container, .jivo_shadow, [src*="//code.jivosite"]').remove();
delete(window.jivo_api);
delete(window.jivo_config);
window.jivo_magic_var = undefined;
window.$jivosite = null;
(function(d,s){
var z = $jivosite=function(c){ z._.push(c) },
el_script = z.s = d.createElement(s),
e=d.getElementsByTagName(s)[0],
jivo_id = 'ID-MY-ACCOUNT';
z.set=function(o){
z.set._.push(o)
};
z._=[];
z.set._=[];
$.async = !0;
el_script.setAttribute("charset","utf-8");
el_script.src='//code.jivosite.com/script/widget/'+jivo_id;
z.t=+new Date;
el_script.type="text/javascript";
e.parentNode.insertBefore(el_script,e)
})(document,"script");
}

Firefox Addon SDK - How to create an about: page

I need to create an about: page, to display addon options. I have seen ti done before, but there seems to be no option in the SDK that allows you to do that.
Is there another way I could let users type about:pagename and get to my page?
I would prefer not to redirect all tabs with a URL of about:pagename to another options page.
Thanks in advance
This is the index.js file for a restartless add-on developed using jpm:
const { Cc, Ci, Cr, Cu, Cm, components } = require("chrome");
Cm.QueryInterface(Ci.nsIComponentRegistrar);
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
// globals
var factory;
const aboutPage_description = 'This is my custom about page';
const aboutPage_id = '6c098a80-9e13-11e5-a837-0800200c9a66'; // make sure you generate a unique id from https://www.famkruithof.net/uuid/uuidgen
const aboutPage_word = 'foobar';
const aboutPage_page = Services.io.newChannel('data:text/html,hi this is the page that is shown when navigate to about:foobar', null, null);
function AboutCustom() {};
AboutCustom.prototype = Object.freeze({
classDescription: aboutPage_description,
contractID: '#mozilla.org/network/protocol/about;1?what=' + aboutPage_word,
classID: components.ID('{' + aboutPage_id + '}'),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
getURIFlags: function(aURI) {
return Ci.nsIAboutModule.ALLOW_SCRIPT;
},
newChannel: function(aURI) {
let channel = aboutPage_page;
channel.originalURI = aURI;
return channel;
}
});
function Factory(component) {
this.createInstance = function(outer, iid) {
if (outer) {
throw Cr.NS_ERROR_NO_AGGREGATION;
}
return new component();
};
this.register = function() {
Cm.registerFactory(component.prototype.classID, component.prototype.classDescription, component.prototype.contractID, this);
};
this.unregister = function() {
Cm.unregisterFactory(component.prototype.classID, this);
}
Object.freeze(this);
this.register();
}
exports.main = function() {
factory = new Factory(AboutCustom);
};
exports.onUnload = function(reason) {
factory.unregister();
};
Basically it registers a custom about page that will be loaded when you access about:foobar. The loaded page is just a line of text.
This is how it looks like:
You can see a working example here: https://github.com/matagus/about-foobar-addon
I think this is a better solution if you are using the addons-sdk:
Credit goes here:
https://stackoverflow.com/a/9196046/1038866
var pageMod = require("page-mod");
pageMod.PageMod({
include: data.url("options.html"),
...
});
var tabs = require("tabs");
tabs.open(data.url("options.html"));
But there are other ways. You could take a look at the Scroll to Top addon which implements this: https://addons.mozilla.org/firefox/addon/402816

gmaps4rails: How to implement a clickable link on a marker

Using Rails 3.2.13, ruby 1.9.3p374 and Gmaps4rails 1.5.6.
I have been strugling with something that, at first, I thought should be fairly straight forward: I want to display a marker that, when clicked, will redirect to a particular path, loading that path in the same window.
Gmaps4rails has no easy option for that in their description. So I spent countless hours searching the web, and the two best hits I found where here in StackOverflow: this smells like the right path, but this one seems also useful.
In the end, my controller looks like:
#gmapsjson = current_user.houses.all.to_gmaps4rails do | house, marker |
marker.title house.reference
marker.json({:link => polymorphic_url(house, :routing_type => :path)})
end
This is correctly (I think) generating the following in the processed html:
<script src="//maps.google.com/maps/api/js?v=3.8&sensor=false&client=&key=&libraries=geometry&language=&hl=&region=" type="text/javascript"></script>
<script type="text/javascript">
Gmaps.map = new Gmaps4RailsGoogle();
Gmaps.load_map = function() {
Gmaps.map.map_options.auto_zoom = false;
Gmaps.map.map_options.zoom = 3;
Gmaps.map.initialize();
Gmaps.map.markers = [{"title":"First House","link":"/houses/1","lat":-3.4671425,"lng":12.5264373},{"title":"Second House","link":"/houses/2","lat":-4.5543296,"lng":-3.4151647}];
Gmaps.map.create_markers();
Gmaps.map.adjustMapToBounds();
Gmaps.map.callback();
};
Gmaps.oldOnload = window.onload;
window.onload = function() { Gmaps.triggerOldOnload(); Gmaps.loadMaps(); };
</script>
Markers appear on the right places. But now, interpreting the described on that first relevant reference, I type directly on view, making sure it will appear below all the other javascripts Gmaps4Rails dumps in the resulting html:
<script type="text/javascript">
function redirect_to(url) {
window.location = url
};
Gmaps.callback = function() {
for (var i = 0; i < Gmaps.map.markers.length; ++i) {
google.maps.event.addListener(Gmaps.map.markers[i].google_object, 'click', redirect_to(Gmaps.map.markers[i].link));
}
};
</script>
But now, whenever I load the page, my Firefox javascript console will say:
TypeError: Gmaps[load_function_name] is not a function
for (key in Gmaps) {
value = Gmaps[key];
searchLoadIncluded = key.search(/load/);
if (searchLoadIncluded === -1) {
load_function_name = "load_" + key;
_results.push(Gmaps[load_function_name]()); <=== Points to this line
} else {
_results.push(void 0);
}
}
So, any ideas on what is wrong?
Thanks in advance,
Marco
Rather than doing it in JavaScript you can just generate all the html including the links is your controller.
Note: To get the link generated correctly I set it up separately and assigned it to a variable
This is what my locations_controller.rb contains:
#json = Location.all.to_gmaps4rails do |location, marker|
location_link = view_context.link_to location.name, location_path(location)
marker.title location.name
marker.infowindow "<h4><u>#{location_link}</u></h4>
<i>#{location.address}</i>"
end
When you set it up correctly you'll get hashes generated that look something like this
{"title":"Home",
"description":"<h4><u>Place</u></h4>
<i>123 E Main St. Anytown, USA</i>",
"lat":29.585019,
"lng":-81.319479}
The wiki page here helped me. Hope this helps you

Combining knockout with sammyjs/pathjs and jquery mobile

I'm trying to combine some of JS libraries to create a mobile SPA website. I'm working with knockoutJS that misses routing engine so I take it from SammyJS or PathJS (haven't decided yet). And I'd like to use jQuery Mobile to get the controls and the mobile design from it.
The thing is that whenever I include the jquery mobile js file into my page the routing engine stops working. Actually it does work, but the window.location.hash get changed not only by me but with jquery mobile itself.
So here is how the code looks like:
in the html file I got a div that I binded to a template
(function ($) {
infuser.defaults.templateUrl = "templates";
console.log('just before pageinit');
$(document).bind('pagecreate', function () {
// disable autoInit so we can navigate to bookmarked hash url
$.mobile.autoInitializePage = false;
// let PathJS handle navigation
$.mobile.ajaxEnabled = false;
$.mobile.hashListeningEnabled = false;
$.mobile.pushStateEnabled = false;
});
$(document).bind('pagebeforechange', function (e, data) {
var to = data.toPage;
if (typeof to === 'string') {
/* var u = $.mobile.path.parseUrl(to);
to = u.hash || '#' + u.pathname;
// manually set hash so PathJS will be triggered
location.hash = to;
// prevent JQM from handling navigation*/
e.preventDefault();
}
});
$(document).bind('pagechange', function (e, data) {
});
var Model = function () {
this.items = ko.observable(null);
this.chosenItemData = ko.observable();
this.state = ko.observable('items');
this.goToItemDetails = function (item) {
location.hash = '/details/' + item.id;
};
};
window.currentModel = new Model();
ko.applyBindings(window.currentModel);
Path.map('#home').to(function () {
currentModel.state(window.templates.items);
currentModel.items(window.dummyData);
});
Path.map('#home/details/:id').to(function () {
var self = this;
$(currentModel.items()).each(function (index, item) {
if (item.id.toString() == self.params['id']) {
currentModel.chosenItemData(item);
currentModel.state(window.templates.itemDetail);
}
});
});
Path.root('#home');
$(function () {
Path.listen();
})
})(jQuery);
Now, you can see that $.mobile.hashListeningEnabled = false; is set to false so the jquery mobile should not listen or react to hash changes whatsoever.
But!
lets say I move from localhost/sammy/#home to localhost/sammy/#home/detail/1
the hash change happens and changes right away to localhost/sammy/home/detail/1
for some reason the hash itself is ommited and the route doesn't get executed.
I sorry if I didnt explain myself better. I'm working on publishing it on a server for everyone to be able to look at it, but, unfortunately it takes time.
Meanwhile, if anyone has any idea what i can do to fix this it will be awesome!
So apparently (and it's written in the jQuery Mobile website the "initmobile" event fires as the script for jquery mobile it attached. To be able attach the event the following lines should be included before the jQuery Mobile script.
<script type="text/javascript">
$(document).on('mobileinit', function () {
$.mobile.ajaxEnabled = false;
$.mobile.hashListeningEnabled = false;
$.mobile.pushStateEnabled = false;
$.mobile.linkBindingEnabled = false;
});
then the onchangehash event in jquery mobile will be disabled.

Resources