I am using Disqus in my ionic v1 project. The browser is working fine but the problem after build apk is not working show me the error
'we were unable to load Disqus. If you are a moderator please see our Troubleshooting guide'
<script type="text/javascript">
var disqus_shortname = 'shortname';
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript';
dsq.async = true;
dsq.src = 'https://'+disqus_shortname+'.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<div id="disqus_thread"></div>
I have been working on an Angular JS based application. I have written a set of gulp commands to uglify/remove comments from JS code. When I run the web application and monitor the network traffic, I noticed that minified(uglified) 'all.js' file consumes quite a lot of time to be loaded (please forget about the caching).
I believe that splitting the all.js file (before or after processing) in to several pieces (let's say four pieces) will improve the application loading time. Please mention if you think there is/are better way(s).
Still I am struggling to find a way to get an approach to above mentioned method under #1. Still no luck :-( Please advice me.
Gulpfile
// include plug-ins
'use strict';
var gulp = require('gulp');
var concat = require('gulp-concat');
var htmlbuild = require('gulp-htmlbuild');
var plugins = require('gulp-load-plugins')();
var es = require('event-stream');
var clean = require('gulp-clean');
var uglify = require('gulp-uglify');
var strip = require('gulp-strip-comments');
var pump = require('pump');
// pipe a glob stream into this and receive a gulp file stream
var gulpSrc = function (opts) {
var paths = es.through();
var files = es.through();
paths.pipe(es.writeArray(function (err, srcs) {
var fixedFiles = [];
for (var i=0; i < srcs.length; i++)
{
fixedFiles[i] = srcs[i].replace("~", ".");
console.log(fixedFiles[i]);
}
gulp.src(fixedFiles, opts).pipe(files);
}));
return es.duplex(paths, files);
};
var jsBuild = es.pipeline(
plugins.concat('all.js'),
gulp.dest('./Scripts/')
);
gulp.task('clean', function () {
return pump(gulp.src('./Scripts/all.js')
.pipe(clean({ force: true })));
});
I have seen some examples of using opencpu together with angular, but no examples of using opencpu in meteor (where angular could be inplemented easily).
Is it as easy as just including ocpu.seturl and jquery.min.js in meteor (as is done here), or does one need to think differently in meteor when using opencpu?
For example, there might be some conflicts between angular and meteor.
I know that is a diffuse question, but I've seen that I'm not the only one who does wonder about it.
Related:
https://groups.google.com/forum/#!topic/opencpu/rEi7lMK65GU
https://www.quora.com/Is-it-possible-to-call-the-R-server-within-a-website-made-with-Meteor-run-some-R-code-then-display-its-output
For example (thanks to http://jsfiddle.net/ramnathv/uatjd/15/):
var myApp = angular.module('myApp', ['angular-meteor']); //added 'angular-meteor'
//set CORS to call "stocks" package on public server
ocpu.seturl("//public.opencpu.org/ocpu/library/graphics/R")
myApp.factory('OpenCPU', function($http){
return {
Dist: function(dist){
var url = "http://public.opencpu.org//ocpu/library/stats/R/" + dist +
"/json"
return $http.post(url, {n: 100})
}
}
})
myApp.controller("HistCtrl", function($scope, $http, OpenCPU){
$scope.dist = 'rnorm'
$scope.dists = ['rnorm', 'runif']
$scope.color = 'blue'
$scope.colors = ['blue', 'red', 'darkmagenta']
$scope.breaks = 10
$scope.submit = function(){
var req = $("#plotdiv").rplot("hist", {
x : $scope.data,
col: $scope.color,
breaks: Math.floor($scope.breaks),
main: $scope.main
});
}
$scope.$watchCollection('[main, color, breaks, data]', function(x){
$scope.submit()
})
$scope.$watch('dist', function(newDist){
OpenCPU.Dist(newDist).success(function(result){
$scope.data = result
})
})
})
Would the above be a "correct" starting point? How should one declare dependencies in meteor (i.e. opencpu, jquery.min.js) ? New to meteor so any suggestions are highly appreciated!
Not using angular (not sure why one would need that), but here is a super basic setup in meteor:
HTML:
<head>
<title>opencpu</title>
<script src="//cdn.opencpu.org/opencpu-0.4.js"></script>
</head>
<body>
<h1>Testing OpenCPU</h1>
{{> hello}}
</body>
<template name="hello">
</template>
JS:
if (Meteor.isClient) {
Template.hello.onRendered(function() {
// ocpu.seturl("//public.opencpu.org/ocpu/library/graphics/R");
// couldn't come up with a good example for this
ocpu.seturl("//public.opencpu.org/ocpu/library/stats/R")
// this gives me a CORS error but the below still seems to work
console.log(ocpu);
var req1 = ocpu.call("rnorm", {n: 100}, function(session1){
var req2 = ocpu.call("var", {x : session1}, function(session2){
session2.getObject(function(data){
alert("Variance equals: " + data);
});
});
});
});
}
All I know about opencpu I've learned in the last 30 minutes -- little! So I don't know how to get past the CORS error. That error doesn't seem to happen when pointing at the graphics package, but for that one I couldn't think of a good example.
I am currently facing a problem with my project's design.
I am using angularjs framework and my task is to provide a translations for a webpage, but the translations need to be provided form the xml file o the BE side.
So since I#ve found out that angulars i18n is configurable on the FE side i had to use another strategy.
I've decided to make a service which fetches the data during a resolve period before everything else is loaded:
app.factory('dictionaryService', ['$http', '$rootScope', function ($http, $rootScope) {
return {
getDictionary: function (defaultLanguage) {
var chosenLanguage = null;
if (angular.isUndefined($rootScope.defaultLanguage) || $rootScope.defaultLanguage == null) {
chosenLanguage = defaultLanguage;
$rootScope.defaultLanguage = chosenLanguage;
} else {
chosenLanguage = $rootScope.defaultLanguage;
}
var translation = new Array();
translation[chosenLanguage] = new Array();
return $http.get('Translation/GetCurrentDictionary/', {
params: {
language: chosenLanguage
}
});
},
GetLanguagesSetup: function () {
return $http.get('Translation/GetLanguagesSetup/');
}
}
}]);
and then resolve it as follows:
$routeProvider.when("/diagnose", {
controller: "diagnoseCtrl",
templateUrl: "/app/views/diagnose.html",
resolve: {
startupData: function (dictionaryService, $q) {
var def = $q.defer();
var translation = new Array();
var startupData = new Array();
var defaultLanguage = "EN";
var dict = dictionaryService.getDictionary(defaultLanguage).then(function (JSONData) {
var keys = Object.keys(JSONData.data.data);
var chosenLanguage = JSONData.data.lang;
translation[chosenLanguage] = {};
for (i = 0; i < keys.length; i++) {
translation[keys[i]] = JSONData.data.data[keys[i]];
}
startupData['translations'] = translation;
def.resolve(startupData);
}).catch(function (e) {
console.log("Translation fetching exception, " + e);
return $q.reject(e);
});
return def.promise;
}
}
});
So as you can see I am storing my fetched translations in a startupData. Then in a controller which is using it I am assigning this data to the $rootScope. It seems already here as a not the best solution, but I could not come up with a different one
Then I have created a translation service which gets the direct translation text:
app.factory('translationService', ['$rootScope', '$http', function ($rootScope, $http) {
var translations = null;
return {
getText: function (key) {
if ($rootScope.cachedTranslations == undefined) {
return key;
}
var result = $rootScope.cachedTranslations[key];
if (result == null) {
return key;
} else {
return result;
}
}
}
}]);
The biggest problem with this solution is, that I am not using promises, but I do not want to make an http query to BE for each translation.
The other problem is with the html template provided by the designers:
<body ng-controller="mainController">
<loading-screen ng-show="!isDataLoaded"></loading-screen>
<div id="header" class="headerView" ng-controller="headerController" ng-show="isDataLoaded">
some header stuff
...
<button ng-bind="option1" ng-click="redirectTo('#subpage1')"></button>
<button ng-bind="option2" ng-click="redirectTo('#subpage2')"></button>
<button ng-bind="option3" ng-click="redirectTo('#subpage3')"></button>
<button ng-bind="language" ng-if="availableLanguages.length > 1" ng-repeat="language in availableLanguages" ng-click="setLanguage(language)"></button>
</div>
</div>
<
<div id="content" ng-view ng-show="isDataLoaded">
</div>
<footer id="footer" class="footer" ng-show="isDataLoaded">
<status-bar></status-bar>
</footer>
Resolve applies only for ng-views's controller, but header stuff needs to be translated as well, so I need to make a headerCtrl somehow wait before it tries to apply translations.
So I have made another unpopular decision to inform all controllers about the finished startup via a broadcast message and to wait until it is all done while showing the loading screen.
It looks fine and is pretty responsive (1sec per startup is acceptable at this point).
The problem is, that I see many design mistakes with this attempt and I just can not come up with the better design.
So my main question is:
How can I make it better? 1st service returns a whole array which is used by the 2nd service so I do not know how to combine it with promises?
I am afraid that with the development of the application I will find myself in a global variables and global events hell
Thanks in advance for your help!
It seems like you are looking for the angular-translate-loader-static-files extension for angular-translate. See the documentation here.
This together with proper configuration of $translateProvider will allow you to fetch json files with translations from the backend or even swap translations on demand - for example user changes language setting, controller reconfigures $translateProvider. Your job is done - everything will be fetched and updated automatically without a page reload.
I am looking the best way to track the Site Activity in Google Analytics for a web app made with Backbone and Requires.
Looking At Google's Page, I found this drop-in plugin - Backbone.Analytics.
My questions are:
1) using Backbone.Analytics, should I change backbone.analytics.js in order to add _gaq.push(['_setAccount', 'UA-XXXXX-X']);?
2) Are there other possible solutions/plugins?
I prefer "do it yourself" style :) It's really simple:
var Router = Backbone.Router.extend({
initialize: function()
{
//track every route change as a page view in google analytics
this.bind('route', this.trackPageview);
},
trackPageview: function ()
{
var url = Backbone.history.getFragment();
//prepend slash
if (!/^\//.test(url) && url != "")
{
url = "/" + url;
}
_gaq.push(['_trackPageview', url]);
}
}
And you add google analytics script to your page as usual.
You shouldn't have to change anything. Just add your Google Analytics code snippet, like normal, and include Backbone.Analytics as you would any other Javascript library.
Just figured i'd share how i'm doing it. This might not work for larger apps but I like manually telling GA when to track page views or other events. I tried binding to "all" or "route" but couldn't quite get it to record all the actions that I need automajically.
App.Router = BB.Router.extend({
//...
track: function(){
var url = Backbone.history.getFragment();
// Add a slash if neccesary
if (!/^\//.test(url)) url = '/' + url;
// Record page view
ga('send', {
'hitType': 'pageview',
'page': url
});
}
});
So i just call App.Router.Main.track(); after I navigate or do anything i want to track.
Do note that I use the new Analytics.js tracking snippet which is currently in public beta but has an API so intuitive that it eliminates the need for a plugin to abstract any complexity what so ever. For example: I keep track of how many people scroll to end of an infinite scroll view like this:
onEnd: function(){
ga('send', 'event', 'scrollEvents', 'Scrolled to end');
}
Good luck.
I wrote a small post on this, hope it helps someone:
http://sizeableidea.com/adding-google-analytics-to-your-backbone-js-app/
var appRouter = Backbone.Router.extend({
initialize: function() {
this.bind('route', this.pageView);
},
routes: {
'dashboard': 'dashboardPageHandler'
},
dashboardPageHandler: function() {
// add your page-level logic here...
},
pageView : function(){
var url = Backbone.history.getFragment();
if (!/^\//.test(url) && url != ""){
url = "/" + url;
}
if(! _.isUndefined(_gaq)){
_gaq.push(['_trackPageview', url]);
}
}
});
var router = new appRouter();
Backbone.history.start();
Regarding other possible solutions/plugins, I've used https://github.com/aterris/backbone.analytics in a few projects and it works quite well as well. It also has options for a few more things like event tracking which can be handy at some point in your analytics integration.
If you use the new universal analytics.js, you can do that like this:
var Router = Backbone.Router.extend({
routes: {
"*path": "page",
},
initialize: function(){
// Track every route and call trackPage
this.bind('route', this.trackPage);
},
trackPage: function(){
var url = Backbone.history.getFragment();
// Add a slash if neccesary
if (!/^\//.test(url)) url = '/' + url;
// Analytics.js code to track pageview
ga('send', {
'hitType': 'pageview',
'page': url
});
},
// If you have a method that render pages in your application and
// call navigate to change the url, you can call trackPage after
// this.navigate()
pageview: function(path){
this.navigate(path);
pageView = new PageView;
pageView.render();
// It's better call trackPage after render because by default
// analytics.js passes the meta tag title to Google Analytics
this.trackPage();
}
}
All answers seem to be almost good, but out-of-date (Sept. 2015). Following 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'...) ):
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')
...
Just posting an update to this question as it seems to be one I get a lot from backbone.js developers I know or work with who seem to fall at the last hurdle.
The Javascript:
App.trackPage = function() {
var url;
if (typeof ga !== "undefined" && ga !== null) {
url = Backbone.history.getFragment();
return ga('send', 'pageview', '/' + url);
}
};
Backbone.history.on("route", function() {
return App.trackPage();
});
The Tracking Snippet:
<head>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||
function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();
a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;
a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script',
'//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXXXX-X', 'auto');
</script>
</head>
The Tracking Snippet should be available on any page you wish to track activity. This could be your index.html where all your content is injected, but some sites may have multiple static pages or a mix. You can include the ga('send') function if you wish, but it will only fire on a page load.
I wrote a blog post that goes in to more detail, explaining rather than showing, the full process which you can find here: http://v9solutions.co.uk/tech/2016/02/15/how-to-add-google-analytics-to-backbone.js.html