angularjs databinding for uploadcare.com doesnt work - angularjs

I'm trying to integrate an upload script into my page. Im using uploadcare.com. They provided a simple directive but I just can't get it to work:
https://github.com/uploadcare/angular-uploadcare/blob/master/angular-uploadcare.js
I'm setting ng-model="test" and in my controller I have the following:
angular.module('testApp')
.controller('MyCtrl', function ($scope) {
$scope.test = "test";
});
The html code looks like that:
<uploadcare-widget ng-model="test" data-public-key="xyz" />
When I check Firebug I can see that the widget works:
<input type="hidden" role="uploadcare-uploader" ng-model="test" data-public-key="6e0958899488d61fd5d0" data-crop="1200:630" value="http://www.ucarecdn.com/ca5513da-90f1-40d1-89e7-648237xxxxxx/-/crop/2560x1344/0,128/-/preview/" class="ng-isolate-scope ng-valid">
But this input value is never populated back to my "$scope.test". Why is that?
When I output $scope.test it still says "test" instead of my image path value.

You can use $watch in angular
$scope.$watch('test', function(newValue, oldValue) {
console.log($scope.test);
});
Or the function provided by uploadcare
$scope.onUCUploadComplete = function(info){
console.log(info);
};
Which is a callback function after image is uploaded

Please check the scope of test model.
You can also update scope variable inside directive like
scope.test = $element.value()

Related

AngularJS - How to pass data from View (HTML) to Controller (JS)

I am really new to AngularJS. I want to pass some object from View (HTML) to my controller (JS).
Actually my Client will send me data in HTML and I have to take that data and process that data in my controller and then display the processed output on screen. He will be using some back-end technology called ServiceNow - https://www.servicenow.com/ .
All the solutions I saw had some event like click event or change event, but in my case this has to be done on page load.
I m using Input type hidden for passing the data to the controller, seems like it's not working.
So is there any other way I can do this ?
Here's the code I am trying to use
<div ng-controller="progressController" >
<input type="hidden" value="ABCD" ng-model="testingmodel.testing">
</div>
app.controller('progressController', function($scope) {
console.log($scope.testingmodel.testing);
});
It says undefined when I console.log my variable in Controller.
You're doing console.log(...) too early. At this time your controller doesn't have any information from the view.
The second problem is that you're binding the view to a variable in controller and not the other way around. Your $scope.testingmodel.testing is undefined and it will obviously the value in the view to undefined.
Solution
Use ng-init to initialize the model and the controller's hook $postLink to get the value after everything has been initialized.
Like this
<div ng-controller="progressController" >
<input type="hidden" ng-model="testingmodel.testing" ng-init="testingmodel.testing = 'ABCD'">
</div>
app.controller('progressController', function($scope) {
var $ctrl = this;
$ctrl.$postLink = function() {
console.log($scope.testingmodel.testing);
};
});
Edit: extra tip
I don't recomment using $scope for storing data since it makes the migration to newer angular more difficult.
Use controller instead.
Something like this:
<div ng-controller="progressController as $ctrl" >
<input type="hidden" ng-model="$ctrl.testingmodel.testing" ng-init="$ctrl.testingmodel.testing = 'ABCD'">
</div>
app.controller('progressController', function() {
var $ctrl = this;
$ctrl.$postLink = function() {
console.log($ctrl.testingmodel.testing);
};
});
You should use the ng-change or $watch
<div ng-controller="progressController" >
<input type="hidden" value="ABCD" ng-model="testingmodel.testing" ng-change="change()">
</div>
app.controller('progressController', function($scope) {
$scope.change = function(){
console.log($scope.testingmodel.testing);
}
});
Or:
app.controller('progressController', function($scope) {
$scope.$watch('testingmodel.testing', function(newValue, olValue){
console.log(newValue);
}
});
If you use ng-change, the function is only called if the user changes the value in UI.
If you use $watch anyway, the function is called.
You can't use value attribute for set or get value of any control, angularJS use ngModel for set or get values.
Here You should try like this way
app.controller('progressController', function($scope) {
//from here you can set value of your input
$scope.setValue = function(){
$scope.testingmodel = {}
$scope.testingmodel.testing = 'ABCD';
}
//From here you can get you value
$scope.getValue = function(){
console.log($scope.testingmodel.testing);
}
});
if you want to bind from html side then you should try like below
<input type="text" ng-model="testingmodel.testing">
<input type="hidden" ng-model="testingmodel.testing">

How do i access a dynamically generated ng-model value of an input field using $scope.$watch in angularjs

I want to access a dynamically generated angular-ngmodel
value of an input field using $scope.$watch.
This is my code snippet below:
<body ng-app="myApp" ng-controller="myCtrl">
<form>
<input type="text" ng-model="<?php echo $product->id ?>" name="prid" />
<input type="submit" value="Add to Cart" ng-click="yea()"/>
</form>
</body>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.yea = function() {
$scope.$watch('xxx', function(){
var test = angular.copy($scope.xxx);
alert(test);
})
};
});
</script>
What I want to do actually: i want to get the dynamic generated value of
the text field above, then pass it through angularJS to a php variable.
So, I thought of the code above but got stucked (do not know what the xxx
wud be). Please, am I doing it the wrong way or is there any solution to
the code above?
Thanks
You could create your own directive:
<my-input my-input-id="{{'<?php echo $product->id ?>'}}"></my-input>
This way php should replace its code with the id, which you will then be able to use in your directive:
app.directive('myInput', function() {
return {
restrict: 'E',
scope: {
myInputId: '#'
},
template: '<input ng-model="myInputId" />'
};
});
Note that I haven't tested if this code really works. If you would create a plunkr or jsfiddle, I will be more than happy to take a look.
But I would personally never print out php in a way like this. Whenever I worked with PHP and Angular, I did HTTP calls from Angular to a PHP API. This way you have a clear separation between your Angular and PHP code.
You can use ngInit to initialize your model, like
<input type="text" ng-init="initPrid(<?php echo $product->id ?>)" ng-model="prId" name="prid" />
And then inside your controller add
$scope.initPrid = function(id) {
$scope.prId = id;
};

Unable to locate FormController instance from parent scope

Problem
I'm trying to access an AngularJS FormController instance (created by setting a name property on a form directive) from it's parent controller scope. The output is undefined.
Confusion
But I can see the controller object as a property on the $scope when I log it to the console. I can also access the object from the template itself using the interpolation directive.
Example
The markup looks like:
<body ng-controller="FooCtrl">
<form name="FooForm" novalidate>
<input name="bar" required>
</form>
</body>
The JavaScript looks something like:
myAngularApp.controller('FooCtrl', function ($scope) {
console.log($scope.FooForm); // undefined
console.dir($scope); // has FooForm peek-a-booing in there
});
Demo
Here is the full plunk: http://plnkr.co/edit/EE7pdBF32B5XRbjZuy8R?p=preview
What am I doing wrong? I'm trying to follow these docs: https://docs.angularjs.org/api/ng/directive/form
The problem here is that your controller is initialized before your template, so at the time you are trying to use it, it's still undefined. Try this:
myApp.controller('MainCtrl', function ($scope) {
$scope.$watch('NewForm', function () {
var outputArea = document.getElementById('output-area');
outputArea.innerHTML = "The FormController instance is: " + $scope.NewForm;
});
});
Also note that using:
outputArea.innerHTML = "The FormController instance is: " + console.dir(newVal);
Doesn't make much sense, you're trying to concat the return value of console.dir to a string, which also always returns undefined ;) Changed it to:
outputArea.innerHTML = "The FormController instance is: " + $scope.NewForm;
Here's a working Plunker: http://plnkr.co/edit/yfVP8hD6saWV2tIok2ER?p=preview
Edit after comment:
If you want to be notified as soon as the form is available on your scope and you don't want to use $watch, you could do that by adding an custom directive to your form element which fires an event:
<form name="NewForm" novalidate formready>
The custom 'formready' directive:
.directive('formready', function(){
return {
restrict: 'A',
compile: function () {
return {
post: function(scope) {
scope.$emit('formready');
}
}
}
};
});
Now in your controller you can do:
$scope.$on('formready', function (event) {
console.log($scope.NewForm); // Available now
});
Here's a working example on Plunker: http://plnkr.co/edit/KG7LEB6EEkBkdONkL9LA?p=preview

My ng-model is not getting updated why

Hey guys here is my code it is not running at all i can't understand i just want to understand why it is not running
http://plnkr.co/edit/vvv3aavAopBhXlc1miUI
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.user=$scope.name;
console.log($scope);
});
This line is wrong:
$scope.user=$scope.name;
You are trying to assign the value of one property on your scope (user) from a non defined property (name)
I think you should be using this kind of approach
app.controller('MainCtrl', function($scope) {
$scope.user="user"
$scope.name="name";
console.log($scope);
});
For demo purposes this will hard code 'user' and 'name' in your input fields, but if you are trying to capture values entered by the user you will probably be using a button with a click handler and in the handler function you can access the user and name values on your scope for further processing, e.g. submit to server via $http
From what I understand you want the second update field to get updated when you type something in the first.
Why it is not working now?
At the moment you are only assigning the value of $scope.name to $scope.user when the controllers loads at start (undefined). You are not watching the value and assigning it to $scope.user when it changes so the value of $scope.user does not update.
Some options on how to make it work
You could use the ngChange directive
In your HTML:
<input type="text" ng-model="name" ng-change="updateUser()">
<input type="text" ng-model="user">
in your controller:
$scope.updateUser = function() {
$scope.user=$scope.name; }
ng-change (Plunkr)
Or (depending on what you are trying to achieve), you could give them the same ng-model:
<input type="text" ng-model="name">
<input type="text" ng-model="name">
same ng-model (Plunkr)

AngularJs can't access form object in controller ($scope)

I am using bootstrap-ui more specifically modal windows. And I have a form in a modal, what I want is to instantiate form validation object. So basically I am doing this:
<form name="form">
<div class="form-group">
<label for="answer_rows">Answer rows:</label>
<textarea name="answer_rows" ng-model="question.answer_rows"></textarea>
</div>
</form>
<pre>
{{form | json}}
</pre
I can see form object in the html file without no problem, however if I want to access the form validation object from controller. It just outputs me empty object. Here is controller example:
.controller('EditQuestionCtrl', function ($scope, $modalInstance) {
$scope.question = {};
$scope.form = {};
$scope.update = function () {
console.log($scope.form); //empty object
console.log($scope.question); // can see form input
};
});
What might be the reasons that I can't access $scope.form from controller ?
Just for those who are not using $scope, but rather this, in their controller, you'll have to add the controller alias preceding the name of the form. For example:
<div ng-controller="ClientsController as clients">
<form name="clients.something">
</form>
</div>
and then on the controller:
app.controller('ClientsController', function() {
// setting $setPristine()
this.something.$setPristine();
};
Hope it also contributes to the overall set of answers.
The normal way if ng-controller is a parent of the form element:
please remove this line:
$scope.form = {};
If angular sets the form to your controllers $scope you overwrite it with an empty object.
As the OP stated that is not the case here. He is using $modal.open, so the controller is not the parent of the form. I don't know a nice solution. But this problem can be hacked:
<form name="form" ng-init="setFormScope(this)">
...
and in your controller:
$scope.setFormScope= function(scope){
this.formScope = scope;
}
and later in your update function:
$scope.update = function () {
console.log(this.formScope.form);
};
Look at the source code of the 'modal' of angular ui bootstrap, you will see the directive has
transclude: true
This means the modal window will create a new child scope whose parent here is the controller $scope, as the sibling of the directive scope. Then the 'form' can only be access by the newly created child scope.
One solution is define a var in the controller scope like
$scope.forms = {};
Then for the form name, we use something like forms.formName1. This way we could still access it from our controller by just call $scope.forms.formName1.
This works because the inheritance mechanism in JS is prototype chain. When child scope tries to create the forms.formName1, it first tries to find the forms object in its own scope which definitely does not have it since it is created on the fly. Then it will try to find it from the parent(up to the prototype chain) and here since we have it defined in the controller scope, it uses this 'forms' object we created to define the variable formName1. As a result we could still use it in our controller to do our stuff like:
if($scope.forms.formName1.$valid){
//if form is valid
}
More about transclusion, look at the below Misco's video from 45 min. (this is probably the most accurate explanation of what transcluded scopes are that I've ever found !!!)
www.youtube.com/watch?v=WqmeI5fZcho
No need for the ng-init trickery, because the issue is that $scope.form is not set when the controller code is run. Remove the form = {} initialization and get access to the form using a watch:
$scope.$watch('form', function(form) {
...
});
I use the documented approach.
https://docs.angularjs.org/guide/forms
so, user the form name, on "save" click for example just pass the formName as a parameter and hey presto form available in save method (where formScopeObject is greated based upon the ng-models specifications you set in your form OR if you are editing this would be the object storing the item being edited i.e. a user account)
<form name="formExample" novalidate>
<!-- some form stuff here -->
Name
<input type="text" name="aField" ng-model="aField" required="" />
<br /><br />
<input type="button" ng-click="Save(formExample,formScopeObject)" />
</form>
To expand on the answer by user1338062: A solution I have used multiple times to initialize something in my controller but had to wait until it was actually available to use:
var myVarWatch = $scope.$watch("myVar", function(){
if(myVar){
//do whatever init you need to
myVarWatch(); //make sure you call this to remove the watch
}
});
For those using Angular 1.5, my solution was $watching the form on the $postlink stage:
$postLink() {
this.$scope.$watch(() => this.$scope.form.$valid, () => {
});
}

Resources