ngSrc is computed before ngIf causing unnecessary http request - javascript

When you write something like:
<img ng-if="image.name != null" ng-src="img/{{ image.name }}_img.png" />
If image.name = null Angular will first add tag and evaluate src. The browser will make http request for img/_img.png wchich doesn't exists. Then angular will remove tag after parsing ngIf directive. What is the simplest way to resolve this issue? I thought that it's perfect use case for ngSrc and ngIf.
EDIT
In current unstable 1.2.0-rc.2 issue is fixed and everything works how it is supposed to do. In current stable 1.0.8 you can't even use ternary operator.

You don't need the ng-if directive for this. Just do a ternary operator test in your expression. Something like
<img ng-src="{{image.name?('img/'+ image.name +'_img.png'):null}}"/>
and it should work. See my plunker http://plnkr.co/edit/BWiGdO?p=preview

You can do it like this with a simple directive.
Here is the HTML :
<!DOCTYPE html>
<html ng-app="App">
<head>
<link rel="stylesheet" href="style.css">
<script src="http://code.angularjs.org/1.2.0-rc.2/angular.js"></script>
<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-controller="MyCtrl">
<h1>Hello Plunker!</h1>
<img ng-directive />
</body>
</html>
Here is the directive with the controller :
angular.module('App', [])
.controller('MyCtrl', function($scope){
$scope.image = {name: "myName"};
});
angular.module('App')
.directive('ngDirective', function($compile){
return {
link: function(scope, element, attrs){
if(scope.image.name != null){
$compile($(element).attr('ng-src', 'http://lauterry.github.io/slides-prez-angular/img/angularjs.png'))(scope);
}
}
}
});
Here is the complete working example : http://plnkr.co/edit/LNgsuX

Related

Angular Property Binding or Interpolation

I am having trouble understanding property binding with interpolation.
The below code is the correct way to assign src for an iframe.
<iframe [src]='sanitizer.bypassSecurityTrustResourceUrl(video.url)' frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
But I would like to concatenate url straight ahead with id. I manage to write the code below but I am sure it is wrong.
<iframe [src]="sanitizer.bypassSecurityTrustResourceUrl("' + https://www.youtube.com/watch?v=' + '"video.id)" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
So can any one guide on how to concatenate strings during binding and interpolation? Also some explanation or link to any guide will be much appreciated.
First
I believe you have just added more quotation marks than necessary. I think that this should work better:
<iframe [src]="sanitizer.bypassSecurityTrustResourceUrl('https://www.youtube.com/watch?v=' + video.id)"></iframe>
Second
I would not recommend sanitizing the input directly inline. I suggest you use component inner logic to sanitize your insecure data. Build the url completaly within some inner function of your component, the odds well might be you would not need the sanitizer at all then.
Please review following working code and review plunkr as well.
https://plnkr.co/edit/tYq22VjwB10WmytQO9Pb?p=preview
index.html
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="style.css" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular-sanitize.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-controller="MainCtrl">
<p>{{movie.src}}</p>
<iframe ng-src="{{trustSrc(movie.src)}}"></iframe>
</div>
</body>
</html>
app.js
var app = angular.module('plunker', ['ngSanitize']);
app.controller('MainCtrl', function($scope, $sce) {
$scope.trustSrc = function(src) {
return $sce.trustAsResourceUrl(src);
}
$scope.movie = {src:"https://www.youtube.com/embed/Lx7ycjC8qjE", title:"Egghead.io AngularJS Binding"};
});

angularjs error, binding doesn't work with this keyword

Couldn't get start with angularjs, need help.
My app.js
var app = angular.module('cartApp', ['ui.router']);
app.controller('dashboardCtrl', function() {
var dash = this;
dash.something = "something";
});
index.html
<!DOCTYPE html>
<html lang="en" ng-app="cartApp">
<head>
<meta charset="UTF-8">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.1/angular-ui-router.js"></script>
</head>
<body ng-controller="dashboardCtrl">{{something}}
/body>
</html>
I think I messed up but don't know where is it.
You have all your bindings available inside controller context(this), so you should use controllerAs pattern to get binding available in this on the view. There you will be using controller alias inside ng-controller directive & you should use dash to get controller binding.
<body ng-controller="dashboardCtrl as dash">
{{dash.something}}
</body>
Also make sure you have referred app.js on the page.
could you try in controller?
app.controller('dashboardCtrl', function($scope) {
$scope.something = "something";
});
For future references, I suggest to follow this great tip.
It's very useful because provide better readability and avoid make these kinds of mistakes.

Angular getting variable value

I'm learning AngularJS and I have problem with data binding.
When I try to get value from $scope.mytext i get {{mytext}}. Here is the code:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>Hello</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js">
</script>
<script>
var MainController = function ($scope) {
$scope.mytext = "Angular JS Rulez";
}
</script>
</head>
<body>
<div ng-app>
<div ng-controller="MainController">
<p>{{mytext}}</p>
</div>
</div>
</body>
</html>`
You had some errors in the way you set up the app.
You never defined the app, you have declared ng-app twice, the second time you haven't assigned anything to ng-app and there was an error with the CDN you referenced. Once you defined the app, you then needed to assign the controller to this app.
The below code will work for you, and you can also see the code working by checking out this jsfiddle demo.
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>Hello</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script>
var myApp = angular.module('myApp',[]);
myApp.controller('MainController', ['$scope', function($scope) {
$scope.mytext = "Angular JS Rulez";;
}]);
</script>
</head>
<body>
<div ng-controller="MainController">
<p>{{mytext}}</p>
</div>
</body>
</html>
Looks like you're calling the app in the html, but you haven't defined it anywhere. You must:
define 'myApp' in the javascript portion, and then
assign the controller on it.
Your code simply calls MainController which isn't defined properly on any app.
A basic setup in this case is, as Paul mentions:
var myApp = angular.module('myApp', []);
myApp.controller(MyAppController, ['$scope', function($scope) {
...add $scope elements here ...
]);
Also you shouldn't need to call ng-app twice in the html.

Getting Started With AngularJS Plunk Issue

I am new to Angular JS. I am trying to start with the basic Hello World Program. Here is my plunk http://plnkr.co/edit/uW1fHB7a17gpvn341sn3?p=preview.
var MainController = function($scope){
$scope.message = "Hello, Angular!";
}
<html ng-app>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div ng-controller="MainController">
<h1>{{message}}</h1>
</div>
</body>
</html>
I created a simple controller and has a single model binding in that. It is not working for me. I am not able to get what the problem is. Can anybody please help me in getting started.
You need to boostrap your app properly and define your controller correctly. Observe the following changes...
<html ng-app="app">
angular.module('app', []).controller('MainController', MainController)
Plunker - updated demo
The AngularJS Getting Started resources should be packed with everything you'd like to know to get up and running
A couple things.
You need to create an angular module:
var app = angular.module('myApp',[]);
The second argument is an array of dependency modules. You don't need one here.
Then change ng-app to ng-app="myApp" referencing whatever you named your module.
Then you need to create a controller the angular way.
app.controller('MainController',MainController);
Here's the full script. Plunkr
function MainController($scope) {
$scope.message = 'Hello World';
}
var app = angular.module('myApp',[]);
app.controller('MainController',MainController);
Your original code works fine with Angular 1.0, just not with 1.4
Just thought it was worth mentioning, in case you were following a tutorial, and wondering why it wasn't working or something.
See this plunkr working fine in 1.0 with equivalent code to yours...
http://plnkr.co/edit/zbWvwxVDvhhVKgc5lGrr?p=preview
<!doctype html>
<html ng-app>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<div ng-controller="MainController">
{{message}}
</div>
</body>
</html>
and
var MainController = function($scope) {
$scope.message = "Hello, Angular!";
}

ng-transclude not working in template AngularJS

Sorry, if something stupid I am missing here, but I really tried various combos to make this code work, but no luck.
I am learning directive in AngularjS from Recipes with AngularJS but stuck at this code -
https://github.com/fdietz/recipes-with-angular-js-examples/tree/master/chapter3/recipe4
I believe it should print Heading before Hello World p text. but its not coming. Let me know what I am missing in my code -
PLNKR CODE
Code as a Whole -
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="utf-8" />
<title>Directive Example</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<script>
var myApp = angular.module("myApp", []);
myApp.directive("myWidget", function(){
return {
restrict: "E",
transclude: true,
template: "<div ng-transclude><h3>Heading</h3></div>"
};
});
</script>
</head>
<body>
<my-widget>
<p>Hello World!!</p>
</my-widget>
</body>
</html>
check the first "h3" before "div"
template: "<h3>Heading</h3><div ng-transclude></div>"
The reason you need to change the recipe is because Angular changed how transclusion works between v1.0 and v1.2.
With change eed299a3, Angular now "clears the translusion point before transcluding."
If you load v1.0 (which is what the github repository uses), you will see "Heading". With v1.2, you won't see "Heading", unless you modify the template the way #Noypi explained.

Categories

Resources