angularjs $watch is not working - angularjs

I have written this code to watch changes in password field,
My code is
var Controllers = angular.module('myapp');
Controllers.controller('SignUpCtrl', function ($scope,$http,$location) {
$scope.$watch($scope.password, validatePasswordFun);
function validatePasswordFun(newValue,oldValue,scope){
console.debug("Test");
}
});
But problem that i am facing is :
on page load, it prints "test" in firebug console,
After that if i enter text/password in password field, it does not execute the function.

You are watching in wrong way it should be string value like
var Controllers = angular.module('myapp');
Controllers.controller('SignUpCtrl', function ($scope,$http,$location) {
$scope.$watch('password', validatePasswordFun);
function validatePasswordFun(newValue,oldValue,scope){
console.debug("Test");
}
});
Internally watch is using $parse service available which expects the property name so you wrap inside a string 'password' so that $parse could work properly
--edit working html
<!DOCTYPE html>
<html ng-app="Demo" >
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script>
</head>
<body ng-controller="test" >
<input type="password" ng-model="password" />
<script>
var app = angular.module('Demo', []);
function test($scope) {
$scope.$watch('password', function (newvalue, oldvalue) {
alert(newvalue);
});
}
</script>
</body>
</html>

Related

How to fix 'undefined' error with $scope.detailsForm

I am new to angularjs and have written a small program but facing the error "scope.detailsForm" as undefined. Could someone help me what is the issue with the below code.
b.js file:
var app = angular.module('my-app', []);
app.controller("my-cont", function($scope) {
$scope.detailsForm.clickme.$setValidity("error1",true);
});
b.html file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script type="text/javascript" src="b.js"></script>
</head>
<body ng-app="my-app" ng-controller="my-cont">
<form method="get" name="detailsForm" ng-model="detailsForm">
<button name='clickme' ng-disabled="detailsForm.clickme.$error.error1">Click Me!</button>
</form>
</body>
</html>
Your problem is that you can not get it when the controller is not built, you need to wait for the html to be processed by Angular. Here's an example.
As you'll see in the console, the first log will echo undefined, and the second will echo the form.
var app = angular.module('MyApp', []);
app.controller("MyCont", ['$scope', function($scope) {
console.log($scope.detailsForm);
$scope.onClicked = function()
{
console.log($scope.detailsForm);
}
}]);

Bind data to controller after bootstrapping an AngularJS application

Is there any way to bind anything you could have written on a form before bootstrapping an AngularJS application?
For example, in this form (also executable in https://jsbin.com/womuyi). How could bind to the controller the data I've written on the input before clicking the bootstrap button?
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="Angular Bootstrap Call Example">
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body ng-controller="MainCtrl as vm">
Please type something before bootstrapping AngularJS
<form>
<input type="text" ng-model="vm.sth"><br/>
You wrote {{ vm.sth }}
</form>
<button onclick="doBootstrap()">Bootsrap AngularJS</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular.min.js"></script>
<script>
angular
.module('main', [])
.controller('MainCtrl', function(){
var vm = this;
// How to bind what I wrote on the input after bootstrap??
});
function doBootstrap() {
angular.bootstrap(document, ['main']);
document.querySelector('button').disabled = 'disabled'
}
</script>
</body>
</html>
Quite ugly, but you can use document to store the values (or any other object that you want) to wait until your app is bootstrapped.
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="Angular Bootstrap Call Example">
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body ng-controller="MainCtrl as vm">
Please type something before bootstrapping AngularJS
<form>
<input id="sthInput" type="text" ng-model="vm.sth"><br/>
You wrote {{ vm.sth }}
</form>
<button onclick="doBootstrap()">Bootsrap AngularJS</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular.min.js"></script>
<script>
angular
.module('main', [])
.controller('MainCtrl', function(){
var vm = this;
vm.sth = document.myBootstrap.sth;
});
function doBootstrap() {
var sthValue = document.querySelector("#sthInput");
document.myBootstrap = {
sth: sthValue.value
};
angular.bootstrap(document, ['main']);
}
</script>
</body>
</html>
Use ng-app directive before controller as below:
<body ng-app="main" ng-controller="MainCtrl as vm">
This will automatically do the bootstrapping for you.
The official documentation for the same can be found at https://docs.angularjs.org/api/ng/directive/ngApp.
you just save value of text box before bootstrap Angular App:-
`beforeData = (document.querySelectorAll(".beforeBootstrap")[0]).value;
angular.bootstrap(document, ['myApp']);
$event.target.disabled = 'disabled';`
see this plunker
I would approach this by doing something along the lines of processing input data before Bootstrap like #elecash suggested, but I would add it to a constant.
(function() {
'use strict';
window.doBootstrap = function() {
window.values = {};
var inputs = document.querySelectorAll('input'),
input;
for (var i = 0; i < inputs.length; i += 1) {
input = inputs[i];
window.values[input.getAttribute('ng-model')] = input.value;
}
angular.bootstrap(document, ['main']);
}
}());
Then in your Angular code:
angular
.module('main', [])
.controller('MainCtrl', ['preBootstrap', function(preBootstrap){
var vm = this;
angular.forEach(preBootstrap, function(value, key) {
var modifiedKey = key.replace('vm.', '');
this[modifiedKey] = value;
}, vm);
}])
.constant('preBootstrap', window.values);

Office.js getFilePropertiesAsync fails on second call in Angular.js

I have an Office Task Pane App written with Office Javascript API (Office.js) that calls Office.context.document.getFilePropertiesAsync and places the returned URL in an angular variable:
$scope.getDocumentUrl = function () {
Office.context.document.getFilePropertiesAsync(function (asyncResult) {
$scope.url = asyncResult.value.url;
});
};
I then have a button that calls this. This works file the first time, but when I press the button a second time, it never enters the callback and displays this error:
TypeError: Object expected at verifyAndExtractCall
(https://localhost:44304/scripts/office/1.1/o15apptofilemappingtable.js:11:54588)
at Anonymous function
(https://localhost:44304/scripts/office/1.1/o15apptofilemappingtable.js:11:83048)
at Anonymous function
(https://localhost:44304/scripts/office/1.1/o15apptofilemappingtable.js:11:86071)
at $scope.getDocumentUrl
(https://localhost:44304/AngularJs/controllers/sandpit.controller.js:130:6)
at $parseFunctionCall
(https://localhost:44304/AngularJs/bower_components/angular/angular.js:12403:7)
at callback
(https://localhost:44304/AngularJs/bower_components/angular/angular.js:21566:17)
at Scope.prototype.$eval
(https://localhost:44304/AngularJs/bower_components/angular/angular.js:14466:9)
at Scope.prototype.$apply
(https://localhost:44304/AngularJs/bower_components/angular/angular.js:14565:11)
at Anonymous function
(https://localhost:44304/AngularJs/bower_components/angular/angular.js:21571:17)
at jQuery.event.dispatch (https://localhos
This is a simplified version of another situation that creates the same error. It also happens with getFileAsync. I know I need $scope.$apply to display the change. I know you can get the URL in other ways. I need to know the cause of the error.
I test your scenario in my local machine. I could not repro your issue.
My simple test app has two files: AngularTest.html and AngularTest.js.
Content in AngularTest.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title></title>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js"></script>
<script src="//ajax.microsoft.com/ajax/4.0/1/MicrosoftAjax.js" type="text/javascript"></script>
<script src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js" type="text/javascript"></script>
<script src="AngularTest.js" type="text/javascript"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<button ng-click="getDocumentUrl()">Get Url!</button>
Url is: {{url}}
</div>
</body>
</html>
Content in AngularTest.js:
(function () {
"use strict";
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.url = "";
$scope.getDocumentUrl = function () {
Office.context.document.getFilePropertiesAsync(function (asyncResult) {
$scope.url = asyncResult.value.url;
});
};
});
Office.initialize = function (reason) {
};
})();
You can obtain the URL by clicking the button "Get Url". I tested it in Excel 2013 SP 1.

Angular, how to select the contents of a text input, with onClick() event on a button?

I am newbie to Angular and web development, I have a text input area that needs to be selected (highlighted) when a button is clicked in Angular.
do I need to something like angular.element(document.getElelmentById(txt1)) and do select on it?
Similar to this thread:
Selecting all text in HTML text input when clicked , the question is, is there a rightway/better way to do this in Angular?
I have searched for an answer, closest I could get was this thread: How to set focus on input field? but couldn't successfully convert the suggestions for select().
Here is my jsfiddle in plain js: http://jsfiddle.net/x62ye14y/, a translation to angular would be greatly appreciated.
<!DOCTYPE html>
<html>
<body>
Select your favorite fruit:
<input type="text" id="id123" placeholder="ENTER VALUE">
<p>Click the button to select text in the textbox</p>
<button onclick="myFunction()">Select Txt</button>
<script>
function myFunction() {
document.getElementById("id123").select();
}
</script>
</body>
</html>
Here is the code I have so far,:
<!DOCTYPE html>
<html ng-app="demo">
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
</head>
<body>
<div ng-controller="DemoCtrl">
<input type="text" ng-model="content" id="txt1"/>
<button ng-click="selectOnClick()">Select Txt</button>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js">
</script>
<script type="text/javascript">
var mod1 = angular.module('demo', []);
mod1.controller('DemoCtrl', function ($scope) {
$scope.content = 'some text';
});
mod1.directive('selectOnClick', function () {
// Linker function
var element1 = angular.element("txt1");
element1.select();
});
</script>
</body>
</html>
http://plnkr.co/edit/DKxAs4QfkLzwAYPxx7tW?p=preview
Simple way to do is using click event.
for example
<input type = "text" (click) = "$event.target.select()">
Can you try this:
http://plnkr.co/edit/PzcINVKw6KNBFxlZUgAS?p=preview
<!DOCTYPE html>
<html ng-app="demo">
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
</head>
<body>
<div ng-controller="DemoCtrl">
<input type="text" ng-model="content" select-on-click />
<p>Content: {{content}}</p>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<script src="app.js"></script>
</body>
</html>
app:
(function (angular) {
var module = angular.module('demo', []);
module.controller('DemoCtrl', function ($scope) {
$scope.content = 'foobar';
});
module.directive('selectOnClick', function () {
// Linker function
return function (scope, element, attrs) {
element.bind('click', function () {
this.select();
});
};
});
}(angular));
you just need to move the select-on-click to a button

Call dart function in angular controller initialization

I try to call a dart function in an AngularJS controller initialization, but I get ReferenceError: myFunction is not defined.
index.dart
import 'dart:js';
myDartFunction() {
return 42;
}
main() {
context['myFunction'] = (JsObject exchange) {
exchange['output'] = myDartFunction();
};
}
My html with AngularJS:
<!DOCTYPE html>
<html ng-app="MyApp">
<head lang="en">
<meta charset="UTF-8">
<title>My Title</title>
</head>
<body>
<div ng-controller="MyCtrl">
<p>{{var}}</p>
</div>
<script type="application/dart" src="index.dart"></script>
<script type="application/javascript" src="../packages/browser/dart.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.js"></script>
<script>
angular.module("MyApp", []).controller('MyCtrl', function($scope) {
var exchange = {};
myFunction(exchange);
$scope.var = exchange['output'];
});
</script>
</body>
</html>
It seems to me, that context['myFunction'] has not been set yet, when controller gets initialized. How can I wait for it and initialize $scope.var?
I found out, that it is possible to use window.onload, which is called after my dart function has been exported to JS. Then I use $scope.$apply to change my scope variable.
angular.module("MyApp", []).controller('MyCtrl', function($scope) {
window.onload = function () {
$scope.$apply(function () {
var exchange = {};
myFunction(exchange);
$scope.var = exchange['output'];
});
}
});
I would suggest to fire an event from Dart after the function was created and execute the code in JavaScript as event handler for this event.

Resources