Controller with scope variable not working - javascript

From Documentation
The syntax InvoiceController as invoice tells Angular to instantiate
the controller and save it in the variable invoice in the current
scope.
We also changed all expressions in the page to read and write
variables within that controller instance by prefixing them with
invoice.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link href="style.css" rel="stylesheet" />
<script data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular.js" data-require="angular.js#1.3.x"></script>
<script src="app.js"></script>
</head>
<body ng-controller="InvoiceController as invoice">
<p>Hello {{invoice.name}}!</p>
</body>
</html>
JS
var app = angular.module('plunker', []);
app.controller('InvoiceController', function() {
this.name = 'World';
});
But it is not working as mentioned in the document. I just moved the inline scripts to external file.
PLUNKER DEMO
Also why it is not working if i pass $scope to the controller function
app.controller('InvoiceController', function($scope) {
$scope.name = 'World';
});

You forgot to set the ng-app
<html ng-app="plunker">
<!-- REST OF HTML -->
</html>

Related

Manipulate scope value with angularjs directive

my model contains some values that I want to modify before showing it to the user. Maybe this is written in the docs and I am to blind to see it.
Lets say I want to display my variable like this
<span decode-directive>{{variable}}</span>
I want to write the decode-directive and it should display variable + 1234 f.e.
I need this at a few points so I can't code it for only one special object.
I hope you can help me out with this.
You just have to use ngSanitize library and include as dependency in your app like this
var app = angular.module('plunker', ['ngSanitize']);
app.controller('MainCtrl', function($scope) {
$scope.name = 'Sören';
});
HTML
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.9/angular.js" data-semver="1.4.9"></script>
<script data-require="ngSanitize#*" data-semver="1.3.15" src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-sanitize.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>{{name}}!</p>
<span ng-bind-html="name"></span>
</body>
</html>
You could use an angular filter for this. If your variable is always html encoded text, an example of the solution would be:
filter('html',function($sce){
return function(input){
return $sce.trustAsHtml(input);
}
})
And then in the html you can use:
<span ng-bind-html="var | html"></span>
Fiddle:
angular.module("app",[])
.filter('html',function($sce){
return function(input){
return $sce.trustAsHtml(input);
}
})
.controller("main", function($scope){
$scope.var= "<Sören"
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="main" >
<span ng-bind-html="var | html"></span>
</div>

AngularJS code only runs in the html file, not in an external file

This AngularJS code works while located in the HTML file:
<!DOCTYPE html>
<html lang="en" ng-app="ChgReqApp">
<head>
<link rel="shortcut icon" href="IM/Coins.png" />
<title>TITLE</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<!-- Change to min -->
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
<script>
angular.module('ChgReqApp', []);
angular.module('ChgReqApp').controller('MainController', function ($scope) {
$scope.ClientInfo = {};
$scope.ChangeRequests = [];
});
</script>
<script src="JS/MainController.js"></script>
</head>
<body ng-cloak ng-controller="MainController">
</body>
</html>
The MainController.js file looks like this and the alert dialog works as expected:
// MainController.js
$(function () {
alert("MainControllerFile");
});
Now, when I move the controller code to the MainController.js file, I get an error:
<!DOCTYPE html>
<html lang="en" ng-app="ChgReqApp">
<head>
<link rel="shortcut icon" href="IM/Coins.png" />
<title>TITLE</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"> </script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<!-- Change to min -->
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
<script>
angular.module('ChgReqApp', []);
</script>
<script src="JS/MainController.js"></script>
</head>
<body ng-cloak ng-controller="MainController">
</body>
</html>
//MainController.js
$(function () {
angular.module('ChgReqApp').controller('MainController', function ($scope) {
$scope.ClientInfo = {};
$scope.ChangeRequests = [];
});
});
The error is:
Error: [ng:areq] Argument 'MainController' is not a function, got undefined
http://errors.angularjs.org/1.4.8/ng/areq?p0=MainController&p1=not%20a%20function%2C%20got%20undefined
at ...
I have searched for a solution to this problem but all the discussions I have found relate to some other issue not applicable to the above code. The external js file is valid and the scripts are in the correct order. Any help on this is greatly appreciated.
There is no need for $(function() {}) because Angular has its own "Document Ready business" (just to simplify to the max :P).
The problem is that Angular can't run its "Document Ready Business" because you are putting Angular stuff inside jQuery's "Document Ready" shorthand and that stops the Angular framework from working properly.
You can read more about this in Angular's documentation
Angular initializes automatically upon DOMContentLoaded event or when
the angular.js script is evaluated if at that time document.readyState
is set to 'complete'. At this point Angular looks for the ng-app
directive which designates your application root.
I think you can see how this conflicts with what you are trying to do.
Also as an additional suggestion go like this:
angular.module('ChgReqApp', []).controller('MainController', function($scope) {
$scope.ClientInfo = {};
$scope.ChangeRequests = [];
});
or like this (my preference)
var app = angular.module('ChgReqApp', []);
app.controller('MainController', function($scope) {
$scope.ClientInfo = {};
$scope.ChangeRequests = [];
});
(function() {
angular
.module("ChgReqApp", [])
.controller("MainController", MainController);
MainController.$inject = ["$scope"];
function MainController($scope) {
$scope.ClientInfo = {};
$scope.ChangeRequests = [];
};
})();
you can read more information here : https://github.com/johnpapa/angular-styleguide
This is what I found that FIXED my problem...
the CHROME browser was CACHING the (MainController.js)
I found this out by looking at (Chrome devtools, Network tab,
MainController.js file, Response TAB) (* THE CODE WAS DIFFERENT
*)
OPEN A NEW TAB in Chrome (fixed the cached MainController.js file)
I was having the same problem. I was just trying to put some VALUES in a MainController.js file EXTERNALLY.
<script src="./js/controllers/MainController.js"></script>
For some reason it wasn't working (from this file)...
But...
when I tested directly from the HTML file (it worked)
app.controller('MainController', ['$scope', function($scope) {
// SCOPE
$scope.test = "test(HTML FILE)";
$scope.test2 = 'test2(HTML FILE)';
}]);
...but NOT IN THE EXTERNAL FILE?
DISABLE CACHE (CHROME)
open CHROME, (DevTools), Networks tab, CLICK (ON) (Disable Cache)
try this
<!DOCTYPE html>
<html lang="en" ng-app="ChgReqApp">
<head>
<link rel="shortcut icon" href="IM/Coins.png" />
<title>TITLE</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"> </script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<!-- Change to min -->
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
<script src="JS/MainController.js"></script>
</head>
<body ng-cloak ng-controller="MainController">
</body>
</html>
//MainController.js
angular.module('ChgReqApp').controller('MainController', function ($scope) {
alert('in main controller');
$scope.ClientInfo = {};
$scope.ChangeRequests = [];
});

Call controller method on angular

This is the fist angular app that I try to make ,let's see
var app = angular.module('miApp', []);
app.controller('CochesController', function($scope) {
$scope.coche ={
marca:"Renault",
modelo:"Clio",
};
$scope.nombreCompleto = function(){
var x = $scope.coche;
return x.marca+" "+x.modelo;
};
})
and the view
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link href="style.css" rel="stylesheet" />
<script data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js" data-require="angular.js#1.4.x"></script>
<script data-require="angular.js#1.4.x" data-semver="1.4.8" src="script.js"></script>
<script src="app.js"></script>
</head>
<body ng-app="miApp" ng-controller="CochesController">
<p>{{coche.nombreCompleto()}}</p>
</body>
</html>
I can use the attributes marca and modelo but I can't use the function ¿whats is wrong?
You could directly call the method available inside a controller scope by methodName, It should be like below,
<p>{{nombreCompleto()}}</p>

Model debounce at non-input

I understand you can put debounce at or anywhere with ng-model. But what if there are multiple ng-model of the same object and one place to "display" it. And I want to set debounce at the "display" element instead.
For example, how do I make name to slowly display in <p> but sync fast in between input:
http://plnkr.co/edit/RZfqDfNGVdswniuPkuIC?p=preview
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.4.x" src="https://code.angularjs.org/1.4.1/angular.js" data-semver="1.4.1"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p ng-model-options="{ debounce: { 'default': 500 } }">Hello {{name}}!</p>
<input ng-model="name" >
<input ng-model="name">
</body>
</html>
JS
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
});

How make that works load and ready together

I have this code... i load in <head> many files.js, this works good... but ... {{sec-intro}} is a variable and has its value, but does not load the file...
<!-- language: lang-js -->
<script type="text/javascript">
$( document ).ready(function() {
jQuery('head').load( 'tpl/head.html' );
});
</script>
<script type="text/javascript">
$( document ).ready(function() {
jQuery('#intro').load( 'tpl/sec-intro-{{sec-intro}}.html' );
});
</script>
I'm not sure if I know what do you mean but you can try this if sec-intro is a javascript variable:
<script type="text/javascript">
$( document ).ready(function() {
jQuery('#intro').load( 'tpl/sec-intro-' + sec-intro + '.html' );
});
</script>
But I think you are confusing with AngularJS notation that uses {{var}}.
EDIT:
Well, first of all variable name can't have hyphen so you need to change that name.
Second thing, you should declare the function in the controller's code. I did a little angular app that is the code:
Script:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.secintro = '01';
$scope.loadFunction = function(){
jQuery('#intro').load('tpl/sec-intro-' + $scope.secintro + '.html');
};
$scope.loadFunction();
});
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="jquery" data-semver="2.1.1" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script data-require="angular.js#1.0.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js" data-semver="1.0.8"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
</body>
</html>
Then you can use loadFunction as angularJS function, i.e: ng-init="loadFunction();"
<body ng-controller="MainCtrl" ng-init="loadFunction();">
</body>
This will execute the function when controller is ready, so you won't need the $scope.loadFunction(); inicialization.
Here is the plunker just print in console the correct string.
I hope this finally works for you.

Categories

Resources