Get data from controller to Component AngularJs - javascript

I have a problem. I create a component in AngularJs and I want to pass data from controller to Component.
Data comes to template component, but in the controller on component is undefined!
This is my code.
The controller
angular.module('testModule')
.controller('testController', ['$scope',
function($scope){
var vm = this;
vm.name = "John";
}
]);
The component. Here in the console.log(vm.name) its undefined! This is my problem.
angular.module('testModule')
.component('testComponent', {
bindings: {
"name": '='
},
controllerAs: 'ctrl',
controller: ['$scope', function ($scope) {
var vm = this;
console.log(vm);
console.log(vm.name);
}],
template: "<h2>Hi {{ctrl.name}}</h2>",
});
HTML
<html ng-app="testModule">
<head>
<title>Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js"></script>
<script src="app.module.js"></script>
<script src="testController.js"></script>
<script src="testComponent.js"></script>
</head>
<body>
<div ng-controller="testController as ctrl">
<test-component name="ctrl.name"></test-component>
</div>
</body>
</html>
Here is the Plunker
Any idea? Thanks!

You should be hooking up over $onInit method to see what component bindings has.
vm.$onInit = function(){
console.log(vm.name);
}
The things which you were trying to do was totally doable till angular 1.5.X, but since AngularJS 1.6+ version they disabled prepopulating context of controller by introducing preAssignBindingsEnabled over $compileProvider. By default it is set to false. If you really want to see this working you could try to set the flag by below code(but I'd not recommend to use this). The main reason behind introducing this change is to make Angular and AngularJS API to look similar by design & architecture, eventually it will make one step closer to migration to Angular.
.config(function($compileProvider){
$compileProvider.preAssignBindingsEnabled(true);
})
Plunker

Related

Pass AngularJS variable to script tag in html view

Here's the issue. I have a 3rd party script which needs to be embedded on my AngularJS app, in the html as a <script> tag. I need to pass scope variables to this script (name, email etc). My first attempt here is to figure out if I can pass a scope variable from the controller to a script tag on page load. Perhaps there's a better approach, like making the script a template, but I'm not sure. I'm worried that if I succeed in this basic concept, that the script tag will render the real data before the variable is passed.
Here's the HTML:
<body>
<div ng-controller="MainCtrl">
Angular variable: {{foo}}
</div>
</body>
<script type="text/javascript">
console.log(foo); // $scope.foo?
</script>
Here's the controller:
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
$scope.foo = 'bar';
})
Plunker: https://plnkr.co/edit/5rcnqUxHRHMthHmkwVuZ?p=preview
If you want to embed third party script(jQuery plugin or something else) to your AngularJS application you should write wrapper to this script(simple directive or component)
The way you presented will not work - I guarantee
I found a simple example for you how to create AngularJS directive and wrap some simple jquery plugin:
<html>
<head>
<title>AngularJS wrapp jquery plugin</title>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="https://raw.github.com/SamWM/jQuery-Plugins/master/numeric/jquery.numeric.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>
<script type="text/javascript">
var app = angular.module('myApp', []);
app.directive('numberMask', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
$(element).numeric();
}
}
});
</script>
</head>
<body>
<div ng-app="myApp">
<div>
<input type="text" min="0" max="99" number-mask="" ng-model="message">
</div>
</div>
</body>

The controller with the name 'mainController' is not registered

i have this code in my script.js file
var mainController = function($scope){
$scope.message = "Plunker";
};
and this is my HTML
<!DOCTYPE html>
<html ng-app>
<head>
<script data-require="angular.js#1.6.1" data-semver="1.6.1" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="mainController">
<h1>Hello {{ message }}</h1>
</body>
</html>
i declared ng-app in the opening html tag
but i get this error on my console that mainController is not registered
To paraphrase http://www.w3schools.com/angular/angular_modules.asp
<div ng-app="myApp" ng-controller="mainController">
{{ firstName + " " + lastName }}
</div>
<script>
var app = angular.module("myApp", []);
app.controller("mainController", function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
});
</script>
The important line is
app.controller("mainController", function($scope)
which injects your controller into your app
The code is following an obsolete example.
Migrating from 1.2 to 1.3
Controllers
Due to 3f2232b5, $controller will no longer look for controllers on window. The old behavior of looking on window for controllers was originally intended for use in examples, demos, and toy apps. We found that allowing global controller functions encouraged poor practices, so we resolved to disable this behavior by default.
To migrate, register your controllers with modules rather than exposing them as globals:
Before:
function MyController() {
// ...
}
After:
angular.module('myApp', []).controller('MyController', [function() {
// ...
}]);
-- AngularJS Developer Guide -- Migrating from 1.2 to 1.3
You need to register your controller with as like this in your script.js file
var app = angular.module('myApp', []);
app.controller('mainController', function($scope) {
$scope.message= "msg";
});
You need to register your controller with the main module of your application.
Try this in your app.js
var myApp = angular.module('app', []);
myApp.controller('mainController', function($scope){
$scope.message = "Plunker";
});
and in your html
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js#1.6.1" data-semver="1.6.1" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="mainController">
<h1>Hello {{ message }}</h1>
</body>
</html>
In case you have your code correct and still getting this error then look in the Console (JS Console) in the browser using inspect window for another JS error shown. Most propably that error will be before this error.
If you solve that JS error then this will get resolved automatically if your code is right. In my case I started getting this error out of the sudden and tried to solve it but nothing work and then I try something else for sometime and saw another error above this error and tried solving it. That was a easy thing to solve and once done this error also got solved by itself.

How to write HTML inside elements with Angular

I'm beginning with Angular, and just wanted to make some tests with Ajax, retrieving a document into my page. It works perfectly, but then a new challenge appeared: I want to be able to add HTML inside a DOM element.
Normally, one would do that from a directive and the templates thingy. But I want to do it at runtime, using a controller.
This is my code:
$http.get("import.html").then(function(response){
var element = document.createElement("div");
element.innerHTML = response.data;
angular.element("#div1").innerHTML(element);
});
Maybe I'm not using correctly "angular.element"? I tried using document.getElementByID, but it doesn't work either. I receive correctly the information from the file, but I just don't find a way I can compile that HTML in runtime.
Any help with this?
edit for showing my full code:
HTML:
<!DOCTYPE html>
<html ng-app="miApp">
<head>
<meta charset="UTF-8">
<script src="angular.js"></script>
<script src="mainmodule.js"></script>
<link rel="stylesheet" href="bootstrap/css/bootstrap.css">
</head>
<body ng-controller="controlador1">
<div id="div1" ng-bind-html="myHtml" style="top:50px;left:50px">
</div>
</body>
</html>
JS:
(tested all your examples, none worked for me, this is the last I used)
app.controller('controlador1', ["$scope", "$http", "$sce", "$compile", function($scope, $http, $sce, $compile) {
$http.get("import.html").then(function(response) {
var parent = angular.element("#div1");
var element = angular.element($sce.trustAsHtml(response.data);
$compile(element)($scope);
parent.append(element);
});
}]);
Usually, you want to compile your HTML if it contains any angular functionality at all (you need to declare '$compile' in your controller dependency list):
myApp.controller('myController', ['$scope', '$sce', '$compile'],
$scope, $sce, $compile) {
$http.get("test.html")
.then(function(response){
var parent = angular.element("#div1");
parent.append($compile(response.data) ($scope));
});
}]);
if you are hell-bent on useing innerHTML, note that angular.element("#div1") is the same as $("#div1") in jQuery. So you need to write angular.element("#div1")[0].innerHTML= ...
Here's a plnkr: http://plnkr.co/edit/p3TXhBppxXLAMwRzJSWF?p=preview
In this, I have made use of $sce. It's a dependency injection of AngularJS, where it treats the HTML as safe to bind. You can read about it in AngularJS site. Please find below code and working jsfiddle for the raised concern:
HTML:
<div ng-app="app" ng-controller="test">
<div>
This is onload HTML
</div>
<div ng-bind-html="dynamicHtml"></div>
</div>
JS
var app = angular.module('app', []);
app.controller('test', function ($scope, $sce) {
$scope.dynamicHtml = $sce.trustAsHtml("<div>This is dynamic HTML!!");
});
[Update]
HTML:
<div ng-bind-html="dynamicHtml"></div>`
JS:
$http.get("import.html").then(function (response) {
$scope.dynamicHtml = $sce.trustAsHtml(response.data); //Assuming 'response.data' has the HTML string
});
You are not using correctly angular. If you use angular, you don't harly ever have to use DOM selector.
Scope is binded with ng-model and {{}} on the view.
Now your answer. To print html on the view, you can do it in that way:
In controller:
$http.get("import.html").then(function(response){
$scope.html = $sce.trustAsHtml(response.data);
});
In view:
<div ng-bind-html="html"></div>
And more easy way:
<ng-include="'url/import.html'"><ng-include>
That's it!!!

What's the best way to fix two AngularJS directives with the same name?

I have a project that's getting quite large. My problem is with clashing 3rd party directives because of... unwisely... chosen directive names, i.e. "datepicker."
Since I use bower for dependency management, I don't want to edit any of the libraries because that would break portability.
How has anyone solved this issue?
After my comment, I created a plunker to see if this workaround is viable and to see how Angular behaves in the case of name clashing but under different modules:
http://plnkr.co/edit/9JKTEfGG4bu47QQIEhBh?p=preview
It seems that if you use different restrictions for different directives then it does work (you need to use the ones that are not mutual on the different directives).
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl as vm">
<div some-directive></div>
<some-directive></some-directive>
<script>
var myApp2 = angular.module('myApp2',[]);
myApp2.directive("someDirective", function() {
return {
restrict: 'E',
template: 'inside myApp2'
};
});
var myApp = angular.module('myApp', ['myApp2']);
myApp.directive("someDirective", function() {
return {
restrict: 'A',
template: 'inside myApp'
};
});
</script>
</body>
</html>
OUTPUT
inside myApp
inside myApp2

AngularJS not working - can't pick up variables

I'm new to web designing and angular, and am copying something similar to this, where I consume a RESTful web service and use AngularJS to display the info in the JSON.
It doesn't seem to be working for me. My main.jsp file looks like:
<!doctype html>
<html ng-app>
<head>
<title>Your Bill</title>
<!-- Include the AngularJS library -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script>
<!-- BillParser script -->
<script type="text/javascript" src="js/app.js"></script>
</head>
<body>
<div ng-controller="GetBill">
<p>The ID is {{bill.id}}</p>
<p>The content is {{bill.content}}</p>
</div>
</body>
</html>
And my app.js looks like:
function GetBill($scope, $http) {
$http.get('http://rest-service.guides.spring.io/greeting').
success(function(data) {
$scope.bill = data;
console.log('INITTED');
});
}
But it looks like the following on localhost/billparser/index:
The ID is {{bill.id}}
The content is {{bill.content}}
Is there something obvious I'm missing here? Excuse the 'bill' naming, it's going to eventually be something relating to bills, I just want to get Angular working first!
It looks like I'm getting the following error:
https://docs.angularjs.org/error/ng/areq?p0=GetBill&p1=not%20a%20function,%20got%20undefined
What do I need to do to fix this? I've never used js before so this is all new to me!
Thanks for your time.
It seems to me that you've missed something here: actually creating a Controller and registering it in your AngularJS application.
From The AngularJS documentation on Controllers (link here), that is what your app.js file should look like:
var myApp = angular.module('myApp',[]);
myApp.controller('GreetingController', ['$scope', function($scope) {
$scope.greeting = 'Hola!';
}]);
That is the featured example. In your case, more precisely, it would be:
var myApp = angular.module('myApp',[]);
myApp.controller('GetBill', ['$scope', '$http', function($scope, $http) {
$http.get('http://rest-service.guides.spring.io/greeting').success(function(data) {
$scope.bill = data;
// console.log('INITTED');
});
}]);
... and that should do it!
I sure hope that you had this inside the controller as:
app.controller('GetBill', ['$scope', '$http', function($scope , $http) {
$http.get('http://rest-service.guides.spring.io/greeting').
success(function(data) {
$scope.bill = data;
console.log($scope.bill);
});
}]);
Check the console for correct data. console.log($scope.bill);
After creating the controller as suggested by the other guys here, depending on your data, you will probably need an ng-repeat in your view.
If, for example, the data returned by getBill is an array of objects; after assigning the data to $scope.bill (which you did already) you would have to go into the view and change it to this:
<div ng-controller="GetBill">
<div ng-repeat="b in bill">
<p>The ID is {{b.id}}</p>
<p>The content is {{b.content}}</p>
</div>
</div>
But if you are not getting an array, you don't have to worry about it.

Categories