how to declare variable outside the controller in angular js - angularjs

I want to declare a variable that I want to use in my two controllers. One controller is for posting values and the second controller is used for getting values from the db. I have used a factory and it returns the time stamp.
This is my code:
mainApp.factory('methodFactory', function () {
return { myMethod: function () {
var date = new Date();
//console.log(date);
var unique = ((date.getMonth()+1) + '' + date.getDate() + '' + date.getFullYear() + ''+ date.getHours() +''+ date.getMinutes() +''+ date.getSeconds());
return unique;
//console.log("methodFactory - myMethod");
}
}
});
When I use methodFactory() in my controllers, the values have changed. Is there any way to have the same values in both of the controllers.

declare using a $rootScope or declare in a service
find the reference
Global variables in AngularJS

It is normal since myMethod() function returns always a new Date(). You don't store the information in the current object.
Store the computed unique variable in a service and provide a getter and a setter to the value in this service.
here a simple example with two controllers where the first controller sets the value in the service and the second controller gets the value from the service:
http://plnkr.co/edit/4WRtfVF3DnOfPDXz9mq0?p=preview
js
var app = angular.module('plunker', []);
app.controller('MainCtrl', MainCtrl);
app.controller('SecondCtrl', SecondCtrl);
function MainCtrl($scope, sharedDataService) {
$scope.setDate= function(){
var date = new Date();
var unique = ((date.getMonth()+1) + '' + date.getDate() + '' + date.getFullYear() + ''+ date.getHours() +''+ date.getMinutes() +''+ date.getSeconds());
sharedDataService.setDate(unique);
}
}
function SecondCtrl($scope, sharedDataService) {
$scope.getDate=function(){
return sharedDataService.getDate();
}
}
app.service('sharedDataService', function() {
var uniqueDate;
this.getDate = function() {
return uniqueDate;
}
this.setDate= function(newDate) {
uniqueDate=newDate;
}
});
html
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.5.x" src="https://code.angularjs.org/1.5.8/angular.js" data-semver="1.5.8"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-controller="MainCtrl">
<button ng-click="setDate()">submit</button>
</div>
<div ng-controller="SecondCtrl">
<div>{{getDate()}}</div>
</div>
</body>
</html>

Related

Two way data binding doesn't work from directive link function angularjs

I'm trying to use variable declared in directive' link: function in directive view html.
Variable which I'm trying to use is int from object which is (this object) declared as $scope variable named slider.
I'm trying to display it:
<div>
{{ slider.step }}
</div>
And printed value is aa : 1 and it's not changing althougt it should be. It's constantly 1 and it don't want to rebind :( although I'm changing this value in code later on. Take a look at full directive code. I'm changing its value in few places:
..in directive link function..
link: function($scope, el) {
$scope.slider = {
step: 1,
changeSlide: function (step) {
if(step === 1) {
this.step = 1;
console.log('changed step to 1: ' + $scope.slider.step);
}
if(step === 2) {
this.step = 2;
console.log('changed step to 2: ' + $scope.slider.step);
}
}
}
$timeout(function () {
var i = 1;
$scope.slider.changeSlide(i);
setInterval(function () {
i++; if(i === 3) i = 1;
$scope.slider.changeSlide(i);
}, 5000);
});
}
I'm chaning step in if(step === 2).
Basically that's correctly working vertical slider. The only missing thing is that I can't access current step from view and I can't display correct active dot of "which slide is currently selected". That's why I need to get this step int in view but I can not.
Here is plnkr demo.
You must use $timeout(function(){ $scope.$apply(); }); after data changed
Working example
angular.module('plunker', []);
function MainCtrl($scope) {
$scope.hello = 'World';
}
angular.module('plunker').directive('elements', function($timeout) {
return {
restrict: 'E',
scope: {
name: '='
},
template: `<div>
{{ slider }}
</div>`,
link: function($scope, el) {
$scope.slider = {
step: 1,
changeSlide: function(step) {
console.log(11, step)
if (step === 1) {
this.step = 1;
console.log('changed step to 1: ' + $scope.slider.step);
}
if (step === 2) {
this.step = 2;
console.log('changed step to 2: ' + $scope.slider.step);
}
$timeout(function(){ $scope.$apply(); });
}
}
var i = 1;
$timeout(function() {
$scope.slider.changeSlide(i);
setInterval(function() {
i++;
if (i === 3) i = 1;
$scope.slider.changeSlide(i);
}, 5000);
});
}
};
});
<!doctype html>
<html ng-app="plunker">
<head>
<meta charset="utf-8">
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="style.css">
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script>
document.write("<base href=\"" + document.location + "\" />");
</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<elements></elements>
</body>
</html>

Angular Storing array into Cookie

I have a function below that works fine and passes info into and retrieves from a cookieStore without issue
$scope.num = 0
$scope.nums = []
$scope.increment = function () {
$scope.num++
}
$scope.$watch('num', function () {
$scope.nums.push($scope.num)
})
$scope.storeProductsInCookie=function(){
$cookieStore.put("invoices",$scope.nums)
};
$scope.getProductsInCookie=function(){
console.log( $cookieStore.get("invoices",$scope.nums));
}
However when I try with the below verufyGuess function that is injecting the Index and no as parameters into the function it fails to place into the cookieStore
$scope.verifyGuess = function (Index , no) {
$scope.votes = {};
$scope.newVotes = []
$scope.votes[Index] = $scope.votes[Index] || 0;
$scope.votes[Index]+= no;
$scope.$watch('votes', function () {
$scope.newVotes.push($scope.votes)
})
$scope.storeProductsInCookie=function(){
$cookieStore.put("invoices",$scope.newVotes)
};
$scope.getProductsInCookie=function(){
console.log( $cookieStore.get("invoices",$scope.newVotes));
}
$cookieStore is Deprecated: (since v1.4.0)
Please use the $cookies service instead.
$scope.nums is an array of strings.So $cookieStore is storing them as string(cookies only support strings to store).
In second case $scope.newVotes is an array of objects. cookies wont store objects.
you must use $cookieStore.put("invoices", JSON.stringify($scope.newVotes))
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.12/angular.js" data-semver="1.4.9"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.12/angular-cookies.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<script>
var app = angular.module('plunker', ['ngCookies']);
app.controller('MainCtrl', function($scope, $cookies) {
$scope.votes = {};
$scope.newVotes = []
var Index = 0;
$scope.votes[Index] = $scope.votes[Index] || 0;
$scope.votes[Index] += 10;
$scope.newVotes.push($scope.votes)
$scope.storeProductsInCookie = function() {
$cookies.put("invoices", JSON.stringify($scope.newVotes))
};
$scope.getProductsInCookie = function() {
console.log($cookies.get("invoices"));
}
$scope.storeProductsInCookie();
$scope.getProductsInCookie();
});
</script>
</body>
</html>

Syntax to access rootScope variable in MyController

In the below code,
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.20/angular.js"></script>
<script type="text/javascript">
function MyController() {
this.Name = "jag";
this.sal = "4500";
}
MyController.prototype.getAnnualSal = function(){
return (this.sal) * 12;
}
var app = angular.module("sample", []).run(function($rootScope) {
$rootScope.variable = 1;
});
app.controller("emp", MyController);
</script>
</head>
<body ng-app="sample">
<div ng-controller="emp as o" >
Hello {{o.Name}}, your annual salary is {{o.getAnnualSal()}}
</div>
</body>
</html>
Using run syntax, $rootScope.variable is introduced at module(sample) level.
What is the syntax to access $rootScope.variable in MyController?
Inject rootScope in controller like this.
angular.module('sample', []).controller('emp', function($scope, $rootScope) {
};
Aside from your issue I dont know why you are mixing controller code in view.Angular is built on MVVM pattern.So separation of controller and view is recommended.
You could do the following, inject $rootScope into the controller
<script type="text/javascript">
function MyController($rootScope) {
this.Name = "jag";
this.sal = "4500";
}
MyController.prototype.getAnnualSal = function(){
return (this.sal) * 12;
}
var app = angular.module("sample", []).run(function($rootScope) {
$rootScope.variable = 1;
});
MyController.$inject = ['$rootScope'];
app.controller("emp", MyController);
</script>

AjaxCallBack was not called, windows phone phonegap

I am trying to connect WCF RESTful C# API to phonegap application using angularjs. My html working perfect in Web but no in my windows phone.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" data-ng-app="myApp">
<head>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="msapplication-tap-highlight" content="no" />
<!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
<link rel="stylesheet" type="text/css" href="css/index.css" />
<title>Profile</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
</head>
<body>
<div>
<div data-ng-controller="ProfileCtrl">
First Name: {{FirstName}}
Last Name: {{LastName}}
</div>
</div>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript">
app.initialize();
</script>
<script type="text/javascript" src="js/jquery-1.11.3.min.js"></script>
<!--<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>-->
<script type="text/javascript" src="js/angular.min.js"></script>
<script>
var myApp = angular.module('myApp', []);
window.jsoncallback = function (json) {
debugger;
if (!json.Error) {
alert("run callback");
//alert("success");
}
else {
alert(json.Message);
}
}
myApp.controller('ProfileCtrl', ["$scope", "$http", function ($scope, $http) {
function LoadProfile() {
debugger;
var call_url = 'http://localhost:53834/LoginService.svc/UserProfile/1';
//For jsonp calling
//alert("Running Jsonp");
//$http.jsonp(call_url).success(function (data) {
// debugger;
//});
alert("Running Ajax");
$.ajax({
url: call_url,
type: "POST",
dataType: "jsonp", // from the server
crossDomain: true,
contentType: "application/json; charset=utf-8", // to the server
jsonpCallback: 'jsoncallback',
success: function (data) {
alert("success");
$scope.FirstName = data.FirstName;
$scope.LastName = data.LastName;
$scope.$apply();
},
}).done(function (data) {
debugger;
console.log(data);
}).fail(function (xhr, status, error) {
debugger;
alert(xhr.status + " " + status + " " + error);
});
};
LoadProfile();
}]);
</script>
</body>
</html>
Here is my html code,
Service code is
public Stream UserProfile(string profileID)
{
TestDBEntities db = new TestDBEntities();
int _ProfileID = Convert.ToInt32(profileID);
tblProfile objtblProfile = db.tblProfiles.Find(_ProfileID);
string jsCode;
JavaScriptSerializer returnList = new JavaScriptSerializer();
string output = returnList.Serialize(objtblProfile);
if (objtblProfile != null)
jsCode = "jsoncallback" + "(" + output + ");";
else
jsCode = null;
WebOperationContext.Current.OutgoingResponse.ContentType = "application/javascript";
return new MemoryStream(Encoding.UTF8.GetBytes(jsCode));
}
I have done all things but not working in my windows phone it is giving an error
200 parserror: jsoncallback was not called
but it is working perfect in Web normally.
The way I made an AJAX request in my application is as below. Take a look and see if this works out for you:
app.ajaxCall = function() {
var xhr = new XMLHttpRequest();
xhr.open('POST', <URL>, false);
//Content-Type can be based on the content you are sending
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
var params = <define param string here>;
xhr.send(params);
var isError = false;
try {
if (xhr.status === 200) {
var jsonResponse = JSON.parse(xhr.responseText);
<logic>
}
};
Hope this helps.

access POST data from httpBackend in e2e test

In this example, I have an e2e test doing a button click, which executes a function that does a POST
I would like to be able to have access to the "data" object from testDev httpBackend callback, in my e2e scenerios code, for verification.
Is this possible in an e2e test? If so, could you point me in the right direction?
thanks
scenerio code
describe('test2 app', function() {
beforeEach(function() {
browser().navigateTo('/testbed/e2e/app/index2.html');
});
it('should run a POST',function() {
element('#myButton2').click();
});
});
test module
var test2Dev = angular.module('test2Dev', ['test2App', 'ngMockE2E'])
.run(function($httpBackend) {
$httpBackend.whenPOST(/testpost/)
.respond(function(method, url, data, headers){
console.log(data);
return [200, data, {}];
});
});
markup
<html lang="en" ng-app="test2Dev" ng-controller="test2Ctrl">
<head>
<meta charset="utf-8">
<title>Test click </title>
<link rel="stylesheet" href="css/app.css">
<link rel="stylesheet" href="css/bootstrap.css">
<script src="lib/angular/angular.js"></script>
<script src="lib/angular/angular-mocks.js"></script>
<script src="/testbed/e2e/test/e2e/test2Dev.js"></script>
<script src="js/controllers2.js"></script>
</head>
<body>
<button id="myButton2" ng-click="runPost()">run post</button>
</body>
</html>
controller
var test2App = angular.module('test2App', []);
test2App.controller('test2Ctrl', function($scope,$http) {
$scope.runPost = function() {
$http.post('/testpost',{
data1 : 'chevy',
data2 : 'ford'
});
}
});
runner
<!doctype html>
<html lang="en">
<head>
<title>End2end Test Runner</title>
<meta charset="utf-8">
<base href="../..">
<script src="app/lib/angular/angular-scenario.js" ng-autotest></script>
<script src="app/lib/angular/angular-mocks.js" ng-autotest></script>
<script src="/testbed/e2e/test/e2e/test2Dev.js"></script>
<script src="/testbed/e2e/test/e2e/scenarios2.js"></script>
</head>
<body>
</body>
</html>
Not very pretty but I removed my test module, and used a changed version of "mockApi" here->
https://github.com/blabno/ngMockE2E-sample (thank you Bernard Labno)
changed e2e.mocks.js to add the data object to it's config obj->
function setup(method, url, config)
{
$httpBackend.when(method, url).respond(function (requestMethod, requestUrl, data, headers) {
config.triggered = true;
config.data = data;
var response = config.response || {};
if (config.serverLogic) {
response = config.serverLogic(requestMethod, requestUrl, data, headers);
}
return [response.code || 200, response.data];
});
}
setup(POST, /testpost/, mocks.api.post_test);
.... and added this method to access it....
chain.getData = function() {
return this.addFuture("get data object for " + itemName, function(done) {
done(null,JSON.parse(api[itemName].data));
});
};
... here is my scenerio now...
it('should run a POST',function() {
element('#myButton2').click();
expect(mockApi("post_test").getData()).toEqual({
data1 : 'chevy',
data2 : 'ford'
});
});
Is there a better way to do this?

Resources