AngularJS: Remove development section when running in production - angularjs

I'm developing an AngularJS application inside Visual Studio 2013. I've added a custom HTML template with some debugging form fields to manipulate my scope when developing the site:
<div data-ng-include="'App/Development/development.html'"></div>
This is fixed in the bottom left corner and make it easier for me to quickly do some actions when testing the site.
But this should be removed when I deploy my website (Release configuration).
Does anyone have a good solution for doing this? Currently my App config and AngularJS is not integrated, so there is no way to tell my Angular application that it is running in production mode.

My solution was to just check the hostname, if localhost I'm showing my development bar.
app.controller('development', function ($scope) {
$scope.debug = document.location.hostname == "localhost";
});

Put an ng-clock on it so the div will not show before angular loads and an ng-if so you will not load ("include") needed sources for a regular user. have the service/controller check the host(property of the window object). if it's local, show the panel using ng-if. you can also have it check the query string. so you can debug on remote by affixing ?debug=true to the Url for example.

Lets assume that you are using mvc with razor
Create a cs file
public class ConfigManager
{
public static bool IsDebugMode()
{
#if DEBUG
return true;
#else
return false;
#endif
}
}
get the value
<script>
app.value('myValue', #ConfigManager.IsDebugMode());
<script>
On your angular controller
app.controller('ctrl', function($scope, myValue) {
//use myValue
$scope.isTestMode = myValue;
});
html
<div data-ng-show="isTestMode" data-ng-include="'App/Development/development.html'"></div>

Related

NW.js - webview - Angular is not defined error

I want control external website using NW.js and webview, but anytime I try this I have error - Angular is not defined.
My source:
index.html
html...head...body...
<webview id="webview" name="webview" src="https://google.com/" allownw></webview>
<script src="../js/script.js"></script>
...body...html
script.js
(function() {
var gui = require('nw.gui');
var win = gui.Window.get();
var webview = document.getElementById("webview");
var tray = new gui.Tray({
icon : 'assets/icon.png'
});
var menu = new gui.Menu();
menu.append(new gui.MenuItem({
type: 'normal',
label: '▶️ Play',
click: function() {
webview.executeScript({code:"var player=angular.element(document.body).injector().get('player'); player.play();"});
}
}));
tray.menu = menu;
}());
This code produce for me error: ReferenceError: angular is not defined
Note: Website google.com is only example.
From the nw.js docs:
loading local files in webview
Add the following permission to the manifest:
"webview": {
"partitions": [
{
"name": "trusted",
"accessible_resources": [ "<all_urls>" ]
}
]
}
and add 'partition="trusted"' attribute to the webview tag.
This is one reason why the <script tag cannot access your ../js/script.js file. I also suggest using a non-relative path to your local file example: chrome-extension://yourdomain/js/script.js (and that it be relative to the root not 'up' a directory).
From google's docs, you can set accessible_resources to be specific patterns or files.
The insertCss, setUserAgentOverride, permissionrequest event, and especially executeScript from google's documentation will likely be of interest to you.
NOTE: you may not want to give that webview access to your nwjs context (allownw) because it can access anything that your program has access to. This is especially true of both an external URL and http where MITM tampering or a third-party change could potentially cause someone to gain elevated access to the PC your application is running on.
For your example, I would keep the script.js outside of the webview and have it instrument the webview via script injection.

How can I de-cache AngularJS templates when they change on the server?

We have an Angular project where the templates have changed numerous times thanks to our "Agile" environment. Browsers seem to strongly cache the templates because of the html file type. This means that when business goes to our dev site after an update, they occasionally see the old templates. How can we make sure that when changes are made to the templates, the user downloads the new template instead of loading from the cache?
We use Jade and to prevent caching, we have a variable based on the time that gets appended to the end of our JS/CSS includes (style.css?v=2012881). Since we already have an 'appVersion' via this variable, I chose to expose that variable using an angular module and constant:
script.
angular.module('appVersion',[]).constant('appVersion',#{curDate});
In my main Angular module I have:
.config(['$httpProvider','appVersion',function($httpProvider,appVersion){
$httpProvider.interceptors.push(function() {
return {
'request': function(config) {
if(!config.cached && config.url.indexOf('.html') > -1){
if(config.url.indexOf("?") > -1){
config.url = config.url.replace("?","?v="+appVersion+"&");
}
else{
config.url += "?v="+appVersion;
}
}
return config;
}
};
});
}])
Since the templates are loaded using $http.get, I added an interceptor that detects if a request is a request for a template and appends the appVersion to the request if it is. That way we have the same versioning for the CSS, JS, and HTML.
Use tools like grunt-filerev (https://github.com/yeoman/grunt-filerev) for static revisioning. They basically add a file content hash, so that caching becomes impossible.

Refreshing web page in real time in sails.js

In my project I am using sails.js. From test1.ejs I am calling a web service which in turn calls another ejs(test2.ejs) using res.view().
Now android user is inputting some values which affects the database and needs to reflect on the web page in real time. I am not able to figure out how this can be achieved using sails.js.
Also I need to even show the android user response and at the same time refresh the web page. In short I want a dynamic UI like share market where any changes on the server is reflected on the front end.
Will I need to use anything else like angularjs?
You can use JavaScript Interface if I understand your problem right.
You should create the class like this:
public class WebAppInterface {
Context mContext;
/** Instantiate the interface and set the context */
WebAppInterface(Context c) {
mContext = c;
}
/** Show a toast from the web page */
#JavascriptInterface
public void showToast(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
}
}
After this you should connect this interface to your webview like this:
webView.addJavascriptInterface(new WebAppInterface(this), "Android");
Now you can call Java code from JS like this:
<script type="text/javascript">
function showAndroidToast(toast) {
Android.showToast(toast);
}
</script>
Or call JS code from Java like this:
webview.loadUrl("javascript:window.showAndroidToast(\"Hello, World!\")");
More info is available here: https://developer.android.com/guide/webapps/webview.html

how to cache angularjs partials?

What's the simplest/modern way of caching partials in angularjs production?
Currently the code looks like:
$routeProvider.when('/error', {templateUrl: 'partials/error.html', controller: 'ErrorCtrl'});
Where the templateUrl is obviously an http path to a separate file. On mobile the loading time for that file is noticeable and I'd love to just cache everything.
The main part of the answer is the $templateCache. An extract:
var myApp = angular.module('myApp', []);
myApp.run(function($templateCache) {
$templateCache.put('templateId.html', 'This is the content of the template');
});
Any of the html templates, can be moved to the $templateCache, and the rest of our application will act as expected (no other changes required)
local-storage as a cache
In case, that we would like to keep the template on the client, we can use the local storage as well. This angular-local-storage extension would simplify lot of stuff.
So, let's adjust the run() to
observe the local-storage, if we do not already have the template on the client
issue the request to load the latest, if needed...
put it into the caches (local-storage and $templateCache)
The adjusted code
.run([ 'localStorageService','$templateCache','$http',
function myAppConfig(localStorageService , $templateCache , $http) {
// The clearAll() should be called if we need clear the local storage
// the best is by checking the previously stored value, e.g. version constant
// localStorageService.clearAll();
var templateKey = "TheRealPathToTheTemplate.tpl.html";
// is it already loaded?
var template = localStorageService.get(templateKey);
// load the template and cache it
if (!template) {
$http.get(templateKey)
.then(function(response) {
// template loaded from the server
template = response.data;
localStorageService.add(templateKey, template);
$templateCache.put(templateKey, template);
});
} else {
// inject the template
$templateCache.put(templateKey, template);
}
}])
So, this way, we do profit from the local-storage. It is filled with the "template" from the server, kept there... and therefore not loaded next time.
NOTE: Very important is also to inject some version key/value and check it. If the Local storage is out-dated... all templates must be reloaded.

Google Analytics don't seem to be firing

I've tried to look around many threads here around GA, I feel like I've done what's required. My site consist of HTML5 and angular.js, the page is structured roughly as follow (through ng-include)
index.html
|-header
--|-navigation
|-content
|-footer
when a link from navigation bar is clicked, the content will change (partials page in angular), header, footer stays the same.
The last script tag in my < head > is as follow (inside index.html)
<script type="text/javascript">
var globalLanguage = 'en';
// GA tracking variable
var _gaq = [['_setAccount', 'UA-XXXXXXXX-X'], ['_trackPageview']];
</script>
and at the bottom part of index.html, before the closing < / body > tag:
<script type="text/javascript">
(function(d, t) {
var g = d.createElement(t), s = d.getElementsByTagName(t)[0];
g.async = 1;
g.src = '//www.google-analytics.com/ga.js';
g.type = 'text/javascript';
s.parentNode.insertBefore(g, s);
}(document, 'script'));
</script>
All my angular controller function, call a common function as described in Tracking Google Analytics Page Views with Angular.js
function gaqPageView($scope, $location, $window) {
console.log('triggering google analytics');
$scope.$on('$viewContentLoaded', function(event) {
console.log('event triggered, tracking: ' + $location.path());
$window._gaq.push([ '_trackPageview', $location.path() ]);
});
}
I do see the console log statements, there's no error in the console either.
When I print out the content of _gaq, I do get an array that grows as I navigate around the page (which mean my _gaq.push call is working just fine).
However, in my the network call (in chrome dev tool), I don't see any _utm.gif call to Google Analytics. (Basics of Debugging Google Analytics Code: GA Chrome Debugger and other tools).
What am I missing here? seems like the google analytics is not firing off the event and reporting it?
Edit: I am pretty sure I am silly here, the _gaq variable itself is just a normal javascript array, so of course _gaq.push work just fine. But what am I missing to get Google Analytics to kick in and start sending the content of that _gaq?
Are you currently running your server on localhost, or an intranet name without a "." -- the tracking GIF request doesn't get made for localhost servers by default.
See Google Analytics GIF request not sent.
Another idea: Usually _gaq is defined as an array only if it's not already defined. If ga.js has already executed, you might be overwriting the _gaq object. It doesn't seem likely from your code organization, but...
Try replacing
var _gaq = [['_setAccount', 'UA-XXXXXXXX-X'], ['_trackPageview']];
with
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXXXXX-X'], ['_trackPageview']);

Resources