Google Analytics and Backbone.js - backbone.js

I am looking for a bit of help, I have been reading documentation on adding Analytics to backbone.js specifically this link and I think I fully understand it, but my issue is do I have to add the analytic tracking code to every page I want analytic's data from, if not can you point me in the right direction.
Any help is much appreciated.
Thank You.

According to the link in the question, you have to include the code only once probably in the router definition file.
The router.js (the file in which Backbone.Router is defined) will look something like this :
router.js
//Include the google-analytics code here, first snippet from the code in
//this http://nomethoderror.com/blog/2013/11/19/track-backbone-dot-js-page-views-with-google-analytics/
var router=Backbone.Router.extend({
initialize: function() {
this.bind('route', this._pageView);
//your custom code goes here
},
_pageView: function() {
var path = Ba1ckbone.history.getFragment();
ga('send', 'pageview', {page: "/" + path});
},
//Other member definitions
});

I recommend you to read this Google devs guide: https://developers.google.com/analytics/devguides/collection/analyticsjs/single-page-applications
Here's my version of the solution (I've added the suggested call to ga('set'...)before ga('send'...) ):
MyRouter = Backbone.Router.extend
...
initialize: () ->
# Track every route and call trackPage
#bind 'route', #trackPage
trackPage: () ->
url = Backbone.history.getFragment()
# Add a slash if neccesary
if not /^\//.test(url) then url = '/' + url
# Analytics.js code to track pageview
global.ga('set', page: url)
global.ga('send', 'pageview')
...

Related

Backbone Route not firing

This should be super basic but I can't get routing working. I should mention that the application is located in a subdirectory called /dist/. Here's my code:
var QuestionRouter = Backbone.Router.extend({
routes: {
"/dist/" : "startTest"
"dist/:id": "getModel"
},
startTest: function(){
console.log('home called')
},
getModel: function(){
app.getModel(id);
}
});
var app = new QuestionView;
var appRouter = new QuestionRouter;
Backbone.history.start({pushState: true});
The URL to trigger this route is:
www.example.com/dist/
www.example.com/dist/12345
Any help would be appreciated.
You'll need to use # (hash symbol).
Backbone routers are used for routing your applications URL's when
using hash tags(#)
This is a quote from a Backbone tutorial: What is a router?
See Backbone's Router documentation
Then your routes would be:
www.example.com/#/dist/
www.example.com/#/dist/12345
You can also use Backbone routes without hashes.
Ok So I was able to work this out:
My route hash should look like this:
routes: {
"" : "startTest",
":id": "getModel"
}
I had to remove pushState: true, with this in place the route wasn't being triggered, not sure why:
Backbone.history.start();

Angularjs $state open link in new tab

I'm trying to implement an "open link in new tab" function using $state.go function. It would be awesome if there was smth like:
$state.go('routeHere', {
parameter1 : "parameter"
}, {
reload : true,
newtab : true // or smth like target : "_blank"
});
Is there any way to do that using AngularJS?
Update: OK, I just solved it using the following code:
var url = $state.href('myroute', {parameter: "parameter"});
window.open(url,'_blank');
I just tried this -- apparently, adding target="_blank" works with ui-sref:
<a ui-sref="routeHere" target="_blank">A Link</a>
Saves the trouble of adding code to your controller, and gives you the URL on hover as with any normal link. Win-win!
I had a similar issue, try this if nothing from previous answers work for you.
var url = '#' + $state.href('preview');
window.open(url,'_blank');
So basically while working in localhost, without appending '#' it was just redirecting to
localhost/preview
, instead of
localhost/Project_Name/#/preview
I'm not taking here about passing the data, just to open $state in new tab.
It may not work on localhost in the event your app is in a subfolder.
I had in fact the same issue.
I have tried online and it worked as expected by using:
<a ui-sref="routeHere" target="_blank">Link</a>
ui-sref="routeHere" href=""target="_blank"
this code solved my problem.
use this in an anchor tag.
The best answered I found, was extending the ui.router, since the feature, does not exist build in.
You may find the full detail here :
Extending the Angular 1.x ui-router's $state.go
However, here is my short explanation of what needs to be done add this to app.js or angular app init file:
angular.module("AppName").config(['$provide', function ($provide) {
$provide.decorator('$state', ['$delegate', '$window',
function ($delegate, $window) {
var extended = {
goNewTab: function (stateName, params) {
$window.open(
$delegate.href(stateName, params, { absolute: true }), '_blank');
}
};
angular.extend($delegate, extended);
return $delegate;
}]);
}]);
In your code
You will be able to do:
$state.goNewTab('routeHere', { parameter1 : "parameter"});
Try this!
<a ui-sref="routeHere({parameter: vm.parameter})" target="_blank"></a>

initial route not executed when going back through history

I have a router defined somewhat similar to the following (greatly simplified for demo purposes here):
var MyRouter = Backbone.Router.extend({
routes: {
'': 'search',
'directions': 'directions',
'map': 'map'
},
search: function () {
// do something
},
directions: function () {
// do something
},
map: function () {
// do something
},
initialize: function () {
this.listenTo(myModel, 'change', this.updateNavigation);
Backbone.history.start({ pushState:true });
},
updateNavigation: function () {
var selected = myModel.get('selected');
this.navigate(selected);
}
});
The history entries are all getting created properly by the updateNavigation call, and when I hit the back-button to go back through the history I've generated, the routes fire for each of the entries, that is until I get to the initial entry. At that point, even though the url has updated with that history entry, the route that should interpret the url at that point does not fire. Any idea what might be going on here? Am I making some bad assumptions about how history works?
EDIT:
It seems I get inconsistent results - it's not always just the initial entry that doesn't execute, it's sometimes anything after the first time I've went back one through history. That is, I click the back-button once, the url changes, the routes fire properly. I hit it again, the url changes, the routes don't fire. It smacks of me doing something wrong, but I haven't a clue.
Don't ask me why, but my browser back button doesn't seem to function properly when I don't trigger: true on #navigate.
My very brief assumption is that Backbone.history.start({ pushState:true }); used in wrong place.
As far as I know, backbone history start should be after the router instance is created. Like,
var router = new MyRouter();
Backbone.history.start({ pushState:true });
I've discovered the problem. I was using a querystring and updating the querystring based on actions within the application. Each time I modified the querystring, I added another history entry, but the actual route parts of the history entry didn't always change. Backbone won't do do anything different based on the same route but with different querystring, so I had to abandon using the querystring and just make restful urls instead. Once I did that, the history worked fine.

Backbone Router not working using boilerplate

Ok, I think this is something simple, however I am being to stupid to see it. Here is my code in backbone using the backbone boilerplate method
require([
"app",
// Libs
"jquery",
"backbone",
// Modules
"modules/example"
],
function(app, $, Backbone, Example) {
// Defining the application router, you can attach sub routers here.
var Router = Backbone.Router.extend({
routes: {
"": "index",
"item" : 'item'
},
index: function()
{
console.info('Index Function');
var tutorial = new Example.Views.Tutorial();
// Attach the tutorial to the DOM
tutorial.$el.appendTo("#main");
// Render the tutorial.
tutorial.render();
},
item: function()
{
console.info('Item View');
}
});
// Treat the jQuery ready function as the entry point to the application.
// Inside this function, kick-off all initialization, everything up to this
// point should be definitions.
$(function() {
// Define your master router on the application namespace and trigger all
// navigation from this instance.
app.router = new Router();
// Trigger the initial route and enable HTML5 History API support
Backbone.history.start({ pushState: true, root: '/reel' });
});
// All navigation that is relative should be passed through the navigate
// method, to be processed by the router. If the link has a data-bypass
// attribute, bypass the delegation completely.
$(document).on("click", "a:not([data-bypass])", function(evt) {
// Get the anchor href and protcol
var href = $(this).attr("href");
var protocol = this.protocol + "//";
// Ensure the protocol is not part of URL, meaning its relative.
if (href && href.slice(0, protocol.length) !== protocol &&
href.indexOf("javascript:") !== 0) {
// Stop the default event to ensure the link will not cause a page
// refresh.
evt.preventDefault();
// `Backbone.history.navigate` is sufficient for all Routers and will
// trigger the correct events. The Router's internal `navigate` method
// calls this anyways.
Backbone.history.navigate(href, true);
}
});
});
I am running this of a MAMP server and when i type Localhost:8888/reel , I get the example index page that comes with boilerplate. However when I type Localhost:8888/reel/item or Localhost:8888/reel/#item I either get, page can not be found or directed back to my index page.
My question is what am i doing wrong. Do I need to use htaccess? This doesnt seem right. Is there a way using backbone to sort this. Sorry if this is really simple, just cant get my head around it.
the problem may lie with the pushState flag.
With that on the request goes all the way to the server and it sees the full url and responds to it with whatever it would do ...
does it work if you have a
$(function (){
setTimeout(navMe, 2000);
});
function navMe() {
backbone.navigate("item");
}
that way 2 seconds after load it will navigate to item view and you know that its because of the request going to the server and not to backbone.

Backbone.js Pushstate: true not returning callback function

I am pretty new to backbone js and I am having some problem getting the pushstate functionality of my app to work. Here is an eg of my route:
var TodoRouter = new (Backbone.Router.extend({
routes: {
"": "index",
"item/add": "AddTodoItem",
"list/add": "AddTodoList"
},
AddTodoItem: function() {
//e.preventDefault();
alert("add new item");
},
AddTodoList: function(e) {
//e.preventDefault();
alert("add new list");
},
Start: function(){
//note: my directory structure is localhost/playground/todo/
Backbone.history.start({pushState: true, root: "/playground/todo/"});
},
initalize: function(){
},
index: function(){
var todoListView = new TodoListView({ collection: TodoItemCollection });
}
}));
Here is how I call my route:
$(function() {
TodoRouter.Start();
});
And lastly here is how I call a link:
New List
The problem that I am running into is that when I call the link, the page stays the same, no alert and the browser displays:
http://localhost/playground/todo/#list/add
Now here is the funny part, if I refresh the page, the url become:
http://localhost/playground/todo/list/add
and I get the alert. So I have a feeling I am missing a key point somewhere. Any help would be greatly appreciated!
You have pushState: true and that's why it preferred the slash / instead of hash #
Either change that or remove the hash
You're trying to use Backbone Routes and html5 pushState.
As the backbone documentation said:
"if you have a route of /documents/100, your web server must be able
to serve that page, if the browser visits that URL directly."
So if you want to trigger some functions through uri (localhost/webapp/#about) you just need to use Backbone Routes.
If you want to use Backbone Routes and pushState, you'll need a back-end to answer requests made to your readable url (localhost/webapp/about) and need to use backbone.navigate method to avoid the browser understand <a href="#someRoute"> as a html anchor.
here you can see a complete example
You can't trigger your route, because when pushState:true the href="#route" has the same behavior as a html anchor.

Resources