loader not showing up in chrome-extension - angularjs

I've an app that retrieve server data using ajax. I've tested in localhost, the loader work fine, but when I install my extension and click on the browser action popup, the loader won't show. The little popup delayed for 2 second and shows the result.
popup.html
<div class="cssLoader" ng-show="loader">Fetching...</div>
js
app.controller('MainControl', function($scope, $http){
$scope.loader = true;
$http({
url: "http://www.corsproxy.com/mydomain.net/items.php",
method: "GET",
}).success(function(data) {
$scope.data = data;
$scope.loader = false;
});
});

Without seeing more of your code it is difficult to know for sure. Nonetheless, my suspicion (based upon the fact that your code works outside of the Chrome extension environment but not inside that environment) is that since you're operating in a Chrome Extension environment, you'll need to include the ng-csp directive (see Chrome documentation or Angular documentation).
I developed an Angular app inside a chrome extension and I needed to use ng-csp in order for Angular to load and fully function properly.
Essentially, Chrome extensions (and even more apps) place a number of restrictive security permissions on the browser environment and ng-csp tells Angular to operate in a way that is more consistent with a strict CSP.
I have included an example below that shows loading the entire Angular application properly:
<!DOCTYPE html>
<html ng-app="myApp" ng-csp>
<head>
<meta charset="utf-8">
<title>My Extension</title>
<link href="css/index.css" rel="stylesheet">
<!-- Include in the next line your Angular library code -->
<script type="text/javascript" src="js/angular-lib.js"></script>
<!-- Include in the next line your custom Angular code such as the $http to load the loader -->
<script type="text/javascript" src="js/myapp.js"></script>
</head>
<body>
<!-- Place your HTML code for the 'Fetching' anywhere here in the body -->
</body>
</html>

According to the docs, CSP "is necessary when developing things like Google Chrome Extensions" (more info can be found on the linked page).
Furthermore, besides defining ng-csp on your root element, there is on more crucial point (which affects ngShow/ngHide):
CSP forbids JavaScript to inline stylesheet rules. In non CSP mode Angular automatically includes some CSS rules (e.g. ngCloak). To make those directives work in CSP mode, include the angular-csp.css manually.
I found this to be necessary only if the angular.js script is defined inside the app's context.
In any case, here is the source code of minimal demo extension that seems to work fine for me:
Structure:
extension-root-dir/
|_____manifest.json
|_____popup.html
|_____popup.js
|_____angular.js
|_____angular-csp.css
manifest.json:
{
"manifest_version": 2,
"name": "Test Extension",
"version": "0.0",
"browser_action": {
"default_title": "Test Extension",
//"default_icon": {
// "19": "img/icon19.png",
// "38": "img/icon38.png"
//},
"default_popup": "popup.html"
}
}
popup.html:
<!DOCTYPE html>
<html>
<head>
<title>Test Extension</title>
<link rel="stylesheet" href="angular-csp.css" />
</head>
<body ng-csp ng-app="myApp" ng-controller="mainCtrl">
<div ng-show="loader">Fetching...</div>
<div ng-hide="loader">{{status}}</div>
<script src="angular.js"></script>
<script src="popup.js"></script>
</body>
</html>
popup.js:
var app = angular.module('myApp', []);
app.controller('mainCtrl', function ($http, $scope) {
$scope.loader = true;
$http({
url: "http://www.corsproxy.com/mydomain.net/items.php",
method: "GET"
}).finally(function () {
$scope.loader = false;
}).then(function (response) {
$scope.data = response.data;
$scope.status = 'Success !';
}, function (response) {
$scope.status = 'ERROR !';
});
});
(BTW, I am using AngularJS v1.2.16.)

Related

Angularjs cookie not working in chrome

Update: When I posted this question, I had been executing the code directly from my desktop. I just put my cookie sample into some angular code running in my localhost server, and I can now successfully create and read cookies from all browsers: Chrome, IE, and Firefox. Are there rules that Chrome follows in regards to creating/reading cookies when code is not being served up from a server?
Original question:
I've created a very simple angularjs application, trying to use make use of angular cookies, and although it works in Firefox and IE, it doesn't seem to work in Chrome.
Here is my html code:
<html ng-app="myApp">
<head>
<meta charset="utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular-cookies.js"></script>
<script src="js/cookieApp.js"></script>
</head>
<body ng-controller="mainCtrl">
</body>
</html>
Here is my angular code:
(function () {
angular.module('myApp', ['ngCookies'])
.controller('mainCtrl', ['$cookies', function($cookies) {
$cookies.put('myFavorite', "cheese");
var favoriteCookie = $cookies.get('myFavorite');
console.log("myFavorite = " + favoriteCookie);
}]);
})();
When I run this code from Firefox and IE, I can see in the console log:
myFavorite = cheese
However, when I run this in Chrome, I see this in the console log:
myFavorite = undefined
The version of Chrome that I'm using is "Version 65.0.3325.181 (Official Build) (64-bit)".
Am I doing something wrong here or is there a setting in Chrome that needs to be adjusted to allow cookies?

AngularJS routing doesn't work with templateUrl?

I tried so hard to get this work but all my tries failed. I'm trying to learn Angular routing, I started very simple: created 4 files in the same folder: index.html, page1.html, page2.html and page3.html.
this is the index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>routing</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<script src="D:\Developer Library\MyAngular\angular.min.js"></script>
<script src="D:\Developer Library\MyAngular\Scripts\angular-route.js"></script>
<body ng-app="myApp">
one
two
three
<div ng-view></div>
<script>
var app = angular.module('myApp', ['ngRoute']);
app.config(function ($routeProvider) {
$routeProvider
.when('/page1', { templateUrl: 'D:\Developer Library\dom\AngularRouting\page1.html' }).
when('/page2', { template: '<h1>page2.html</h1>' })//the template is working fine unlike templateUrl
.when('/page3', { template: '<h1>page3.html</h1>' });
//page1.html, page2.html, page3.html are just files holding headers with some text.-->
})
</script>
</body>
</html>
I got these errors in the console window:
XMLHttpRequest cannot load
file:///D:/Developer%20LibrarydomAngularRoutingpage1.html. Cross
origin requests are only supported for protocol schemes: http, data,
chrome, chrome-extension, https, chrome-extension-resource.
and:
Error: [$compile:tpload]
http://errors.angularjs.org/1.5.8/$compile/tpload?p0=D%3ADeveloper%20LibrarydomAngularRoutingpage1.html&p1=-1&p2=
at angular.min.js:6
at angular.min.js:156
at angular.min.js:131
at m.$eval (angular.min.js:145)
at m.$digest (angular.min.js:142)
at m.$apply (angular.min.js:146)
at HTMLBodyElement. (angular.min.js:115)
at Sf (angular.min.js:37)
at HTMLBodyElement.d (angular.min.js:37)
I made every possible change to get it work: I changed the href value of the anchor elements to /#/page1, #/page1, /page, page , I also changed the templateUrl value to similar values (my last try was the full path of the file!)
I'm actually confused between the href value and the first parameter of when method and the templateUrl, so I have some questions that I think will help me understand how routing work in angular:
What each of them refers to: are the href and the first argument of when method the same?
Can I assign the href attribute any value, and refer to it in the when argument?
Is templareUrl value related to the location of the current file(index.html),
What does the hash symbol # mean and why it's important?
Angular is loading templates via AJAX, and AJAX can not access local file system.
You must run you app on a server (you can use local server) for templateUrl to work.

Create states from json file / http

I have a backend which is generating a json file containing information about the most important pages. I would like to load this json file, and build corresponding states based on the data in the file. I can't inject $stateProvider into .run or .controller, and I can't inject $http into .config, so I am feeling a bit lost.
So the question is. How I can load a json file, go through the data and build states based on this data?
Quick edit: If I am lacking in providing the necessary information, please tell, and I'll try and improve the question.
I've attempted to solve a similar problem and created UI-Router Extras "Future States". Future states tries to solve additional problems, such as lazy loading using RequireJS, placeholders for entire unloaded modules, and routing by bookmarked URL to unloaded placeholders.
Here is a plunk demonstrating how to use Future States for your use case: http://plnkr.co/edit/Ny7MQcmy35dKeEjbw57d?p=preview
I tried using the stackoverflow snippet runner, but had problems, so here is a non-runnable paste of the code.
JS:
// Code goes here
var app = angular.module("jsonstates", ["ct.ui.router.extras"]);
app.config([ '$stateProvider', '$futureStateProvider',
function($sp, $fsp ) {
var futureStateResolve = function($http) {
return $http.get("states.json").then(function(response) {
angular.forEach(response.data, function(state) {
$sp.state(state);
})
})
}
$fsp.addResolve(futureStateResolve);
console.log($fsp);
}]);
app.controller("someCtrl", function() { })
Html:
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#1.2.25" data-semver="1.2.25" src="https://code.angularjs.org/1.2.25/angular.js"></script>
<script src="https://rawgit.com/angular-ui/ui-router/0.2.11/release/angular-ui-router.js"></script>
<script src="https://rawgit.com/christopherthielen/ui-router-extras/0.0.10/release/ct-ui-router-extras.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="jsonstates">
<h1>Hello Plunker!</h1>
Top state Nested state
<div ui-view></div>
</body>
</html>
Json:
[
{
"name": "top",
"url": "/top",
"controller": "someCtrl",
"template": "<h1>top state</h1><div ui-view></div>"
},
{
"name": "nested",
"parent": "top",
"url": "/nested",
"controller": "someCtrl",
"template": "<h1>nested state</h1><div ui-view></div>"
}
]

AngularJS. $resource, MongoLab, Restful API - What's wrong with my sample?

I am new to AngularJS and loving it as I learn it. I am trying to figure out how to communicate with MongoLab from AngularJS using $resource and RESTful API. I have the following two files:
index.html:
-----------
<!DOCTYPE html>
<html lang="en">
<head>
<title>MongoLab Connectivity Test</title>
<script src="angular.js"></script>
<script src="angular-resource.js"></script>
<script src="app3.js"></script>
<link rel="stylesheet" href="bootstrap.css" />
<link rel="stylesheet" href="bootstrap-theme.css" />
</head>
<body ng-app="myModule">
<div ng-controller="display">
<p>{{data.message}}</p>
</div>
</body>
</html>
app3.js:
--------
var myModule = angular.module('myModule', ['ngResource']);
myModule.controller('display', function($scope, personService) {
$scope.data = personService.query();
});
myModule.constant({
DB_BASEURL: "https://api.mongolab.com/api/1/databases/db1/collections",
API_KEY: "<MyAPIKey>"
})
myModule.factory('personService', ['$resource', 'DB_BASEURL', 'API_KEY',
function($resource, DB_BASEURL, API_KEY)
{
return $resource
(DB_BASEURL+'/persons/:id'
,{id: "#id" apiKey: API_KEY}
);
}
]);
When I try it, I get the following output:
{{data.message}}
I am not sure what I am doing wrong. Hoping to get some help.
A better way to connect would be : https://github.com/pkozlowski-opensource/angularjs-mongolab
[copying the text from documentation AS IT IS]
Usage instructions
Firstly you need to include both AngularJS and the angular-mongolab.js script : https://raw.githubusercontent.com/pkozlowski-opensource/angularjs-mongolab/master/src/angular-mongolab.js
Then, you need to configure 2 parameters:
MongoLab key (API_KEY)
database name (DB_NAME)
Configuration parameters needs to be specified in a constant MONGOLAB_CONFIG on an application's module:
var app = angular.module('app', ['mongolabResourceHttp']);
app.constant('MONGOLAB_CONFIG',{API_KEY:'your key goes here', DB_NAME:'angularjs'});
Then, creating new resources is very, very easy and boils down to calling $mongolabResource with a MongoDB collection name:
app.factory('Project', function ($mongolabResourceHttp) {
return $mongolabResourceHttp('projects');
});
As soon as the above is done you are ready to inject and use a freshly created resource in your services and controllers:
app.controller('AppController', function ($scope, Project) {
Project.all().then(function(projects){
$scope.projects = projects;
});
});
Also, you may check out the blog here for even simpler implementation : http://asad.io/angularjs-with-mongolab/
Use the $http module by Angular and Mongolab REST API
For GET request,
$http.get('https://api.mongolab.com/api/1/databases/DATABASE_NAME/collections/COLLECTION_NAME?apiKey=YOUR_API_KEY')
.success(function(data) {
console.log(data)
}
For POST request,
$http.post('https://api.mongolab.com/api/1/databases/DATABASE_NAME/collections/COLLECTION_NAME?apiKey=YOUR_API_KEY', $scope.data, {
headers: {
'Content-Type': 'application/json; charset=UTF-8'
}
})
.success(function() {
console.log('Data saved successfully')
}
More on http method support documentation - http://docs.mongolab.com/data-api/#reference

BTC Guild API Parsing Issue with AngularJS

I am trying to get some basic information from the BTC Guild API through AngularJS, but all it does is run in the error function and gives no output as to what the error is. Firebug shows nothing in the error object when breaking in that function. Any ideas?
jsfiddle link: http://jsfiddle.net/bX3ar/11/
javascript:
angular.module('BTCGuild', []);
function BTCGuildCtrl($scope, $http) {
$http.get('https://www.btcguild.com/api.php?api_key=').success(function (response) {
$scope.error = 'response:' + response;
$scope.unpaidRewards = response.user.unpaid_rewards;
}).error(function (error, status) {
$scope.error = 'error:' + error + status;
});
}
html:
<!doctype html>
<head>
<script type="text/javascript" src="http://code.angularjs.org/1.1.5/angular.min.js"></script>
<script type="text/javascript" src="btcguild.js"></script>
</head>
<html ng-app="BTCGuild">
<body>
<div ng-controller="BTCGuildCtrl">
<table>
<p>{{unpaidRewards}}</p>
<p>Error:{{error}}</p>
</table>
</div>
</body>
</html>
A couple of notes:
You're going to get a "Cross Origin Request" error. Here's a snippet of the response after fixing it:
OPTIONS https://www.btcguild.com/api.php?api_key= No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://fiddle.jshell.net' is therefore not allowed access.
Take a look at these notes on how to properly format a JSFiddle for Angular: Frameworks & Extensions should be No Library - pure JS, and No wrap, in . Also, you'll want to put this under Fiddle Options: Body Tag <body ng-app="BTCGuild">
Here is the updated JSFiddle: http://jsfiddle.net/bX3ar/14/
If you can get through the CORs issue, you'll see this work. Or if you put in a fake response, you can see it display properly.

Resources