Can't inject HTML into an angular page - html

I want to inject html into an angular page
My controller starts with:
myapp.controller("myCtrl", function ($scope, $http, $stateParams, $sce) {
$scope.renderHtml = function(html_code) {
return $sce.trustAsHtml(html_code);
};
$scope.pgf = "<p>Hello</p>";
And on my HTML page I have:
<div class="intro"> AA {{renderHtml(pgf)}} AA </div>
And in the browser, I see:
AA <p>Hello</p> AA
Where what I want is
AA
Hello
AA
Is this a version problem- how do pick a consistent set of versions? (If I just raise the versions, I get all sorts of errors...)

You have to use ng-bind-html (angular ngBindHtml docs) to bind HTML content...
CONTROLLER
function myCtrl($scope, $sce) {
$scope.renderHtml = function(html_code) {
return $sce.trustAsHtml(html_code);
};
$scope.pgf = "<p>Hello I'm a Bear</p>";
}
HTML
<div ng-bind-html="renderHtml(pgf)"></div>
Additionally, here you are a working PLUNKER with your example.

So your Angular code works but you didn't place your html binding in the right place.
You can't set a function inside angular binding {{ function }}
So in your HTML should say <div ng-bind-html="trustHTML(pgf)"></div>

Try ngBindHtml directive in module ng. It provides a secure way of binding content to an HTML element.
Syntax :
<element ng-bind-html="expression"></element>
DEMO
var app = angular.module('myApp', []);
app.controller('MainCtrl', ['$scope', '$sce', function($scope, $sce) {
$scope.renderHtml = function(html_code) {
return $sce.trustAsHtml(html_code);
};
$scope.pgf = "<h1>Hello I'm a Bear</h1>";
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MainCtrl">
<div ng-bind-html="renderHtml(pgf)"></div>
</div>

Related

AngularJS, how to display contents of a received JSON object

I have successfully received the JSON object from an API, which is evident from a console.log code. Now, I want to display the various elements in that JSON file. For example, the JSON contains elements like "name" and "url". How do I display these individually, in an h1 HTML element, after clicking the submit button and fetching the JSON file. I'm a newbie and sorry if this is an obvious question, I'm kinda stuck and need help. Thank you in advance!
My HTML Code is:
<body ng-app="myApp">
<div ng-controller="UserCtrl">
Search : <input type="text" placeholder="Search Employees"
ng-model="formData.searchText"/> <br/><br/>
<button ng-click="getByID()">Submit</button>
{{response.data.name}}
</body>
The JS is:
var myApp = angular.module('myApp', []);
myApp.controller('UserCtrl', function($scope, $http) {
var id = "my secret key comes here";
$scope.formData = {};
$scope.searchText;
$scope.getByID = function() {
$http.get("https://rest.bandsintown.com/artists/" + $scope.formData.searchText + "?app_id="+id)
.then(response => {
console.log(response.data.name)
})
}
});
Thank you so much in advance!
You need to use a variable to assign it with the response data and then use it in html. For example to display name from response.data.name:
<body ng-app="myApp">
<div ng-controller="UserCtrl as vm">
Search : <input type="text" placeholder="Search Employees"
ng-model="vm.searchText"/> <br/><br/>
<button ng-click="vm.getByID()">Submit</button>
<h1>{{ vm.name }}</h1>
</body>
In controller:
var myApp = angular.module('myApp', []);
myApp.controller('UserCtrl', function($http) {
let vm = this;
var id = "my secret key comes here";
vm.searchText;
vm.name;
vm.getByID = function() {
$http.get("https://rest.bandsintown.com/artists/" + vm.searchText + "?app_id="+id)
.then(response => {
console.log(response.data.name);
vm.name = response.data.name;
})
}
});
Put the data on $scope:
$scope.getByID = function() {
var url = "https://rest.bandsintown.com/artists/" + $scope.formData.searchText;
var params = { app_id: id };
var config = { params: params };
$http.get(url, config)
.then(response => {
console.log(response.data.name)
$scope.data = response.data;
})
}
Then use the ng-repeat directive:
<body ng-app="myApp">
<div ng-controller="UserCtrl">
Search : <input type="text" placeholder="Search Employees"
ng-model="formData.searchText"/> <br/><br/>
<button ng-click="getByID()">Submit</button>
{{data.name}}<br>
<div ng-repeat="(key, value) in data">
{{key}}: {{value}}
</div>
</div>
</body>
For more information, see
AngularJS ng-repeat Directive API Reference

how to call JSON data through URL in Angular JS

I'm practicing Web API through JSON.
In the URL I am using (https://www.ebi.ac.uk/europepmc/webservices/rest/search?query=malaria&format=json), there are fields like ID, titles etc. I want to call title and display it. Below is my code so far:
app.controller("europepmc", ['$scope', '$http', function($scope, $http) {
$http.get('https://www.ebi.ac.uk/europepmc/webservices/rest/search?query=malaria&format=json')
.success(function(data) {
$scope.magazine = data;
});
}]);
And my controller is binding with html date in the following way:
<div ng-controller="europepmc">
<p>The magazine title is is {{magazine.title}}</p>
</div>
After successfully developing this code I'm not able to get the title.
The JSON you are receiving has more properties for you to go through before you can reach title from results. You should extent it with .resultList.result first. Then display this array with ng-repeat.
Here is a demo:
var app = angular.module("pmc", []);
app.controller("europepmc", ['$scope', '$http', function($scope, $http) {
$http.get('https://www.ebi.ac.uk/europepmc/webservices/rest/search?query=malaria&format=json')
.then(function(res) {
$scope.magazines = res.data.resultList.result;
});
}]);
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body>
<div ng-app="pmc" ng-controller="europepmc">
<div ng-repeat="magazine in magazines">
{{magazine.title}}
<hr>
</div>
</div>
</body>
</html>
Here is a demo to view the entire response:
var app = angular.module("pmc", []);
app.controller("europepmc", ['$scope', '$http', function($scope, $http) {
$http.get('https://www.ebi.ac.uk/europepmc/webservices/rest/search?query=malaria&format=json')
.then(function(res) {
$scope.magazine = res.data;
});
}]);
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body>
<div ng-app="pmc" ng-controller="europepmc">
<pre>
{{magazine | json}}
</pre>
</div>
</body>
</html>
your Json object does have the title property, but a bit deeper:
object.resultList.result.0-24.title
to look at it better, paste your Json here:
http://jsonviewer.stack.hu/
and check the viewer tab.
//In Angular Controller Code
var app = angular.module("myApp", []);
app.controller("europepmc", ['$scope', '$http', function ($scope, $http) {
$http({
method: 'GET',
dataType: 'json',
url: 'https://www.ebi.ac.uk/europepmc/webservices/rest/search?query=malaria&format=json',
}).then(function (success) {
$scope.magazineList = success.data.resultList.result;
}, function (error) {
alert(error);
});
}]);
// HTML Page Code
Use ng-repeat to loop through mg in magazineList -- and then use mg.title

Edit HTML outside ng-view on route change

I want to change some HTML in the navbar upon a route change, using the routing information. I can almost get it to work with the code below, but the data is not parsed as HTML when arriving in the DOM. I tried using the $sce service, but that didn't really get me anywhere.
If there are any other (better) ways of editing the HTML on route change, then please let me know.
HTML:
<nav>
<div ng-controller="BrandCtrl">
<div class="nav-brand">
{{brand}}
</div>
</div>
</nav>
<div ng-view></div>
JS:
var app = angular.module("app", ['ngRoute']);
app.controller("BrandCtrl", function($scope, $route) {
$scope.$on('$routeChangeSuccess', function() {
var html = $route.current.html;
$scope.brand = html;
});
});
app.config(function ($routeProvider) {
$routeProvider
.when('/next-page', {
templateUrl: 'partials/next-page.html',
controller: 'BrandCtrl',
html: '<h3>New brand</h3>'
});
You should be changing the HTML via the 'views' in the routes.
$stateProvider.state('app',{url: 'someurl',
views: {
'topnav': { templateUrl: 'path/to/some/html',
controller: 'navcontroller'},
'mainContent': {templateUrl: 'path/to/some/other/html',
controller: 'contentcontroller'} }
});
In your HTML you would have multiple views:
<div ui-view="topnav"></div>
<div ui-view="mainContent"></div>

Understanding scope in directive's childs

I'm trying to understand "scopes" in agularJS and i can't understand the following piece of code:
HTML:
<body ng-app="myModule">
<div ng-controller="MyCtrl">
<my-component>
<h2>Attribute</h2>
{{isolatedAttributeFoo}}
</my-component>
<my-component>
<h2>Attribute</h2>
{{isolatedAttributeFoo}}
</my-component>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="app.js"></script>
AngularJS:
var myModule = angular.module('myModule', [])
.directive('myComponent', function () {
return {
restrict:'E',
scope:{}
};
})
.controller('MyCtrl', ['$scope', function ($scope) {
$scope.isolatedAttributeFoo = 'Hello!';
}]);
As you can see it is a very simple test. As far as i know (from this example), the childs of a directive (in the example, the elements inside "my-component") inherit the scope from the directive and, since the "my-component" scope is isolated, the "isolatedAttributeFoo" variable should NOT take the value from the "isolatedAttributeFoo" variable at the controller... But it does. Why? Am i misunderstanding something?
If you want to try it, here is the Fiddle.
You can only isolate the scope when you include the template or templateUrl in the directive definition. Other wise it will only inherit from parent and view won't even recognize any changes to scope made in link or controller of directive
Try the following:
HTML
<my-component></my-component>
JS
.directive('myComponent', function () {
return {
restrict:'E',
template: ' <h2>Attribute</h2>{{isolatedAttributeFoo}}',
scope:{},
link:function(scope){
scope.isolatedAttributeFoo = 'Good Bye!';
}
};
});
DEMO
I think this will be clear:
Here is a fiddle:
https://jsfiddle.net/kst65t0p/3/
var myModule = angular.module('myModule', [])
.directive('myComponent', function () {
return {
restrict:'E',
scope:{},
link : function(scope){
alert(scope.isolatedAttributeFoo);
}
};
})
.controller('MyCtrl', ['$scope', function () {
this.isolatedAttributeFoo = 'Hello!';
}]);
<div ng-app="myModule" ng-controller="MyCtrl">
<my-component>
<h2>Attribute</h2> {{MyCtrl.isolatedAttributeFoo}}
</my-component>
<my-component>
<h2>Attribute</h2> {{MyCtrl.isolatedAttributeFoo}}
</my-component>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
Your scope is isolated into the link function.
The link function is to a directive what a controller is to the view.

Argument 'NavController' is not a function, got undefined

i get this error when i start the app
this is the controller:
myApp
.controller('NavController',
['$scope', '$location', function ($scope, $location) {
$scope.navClass = function (page) {
var currentRoute = $location.path().substring(1) || 'main';
return page === currentRoute ? 'active' : '';
};
}]);
and this is the app.js:
angular.module('myApp',[
'ngRoute'])
.config(['$routeProvider',
function($routeProvider){
$routeProvider
.when('/',{
templateUrl:'views/main.html',
controller: 'mainCtrl'
})
.when('/team1',{
templateUrl:'views/team1.html',
controller: 'mainCtrl'
})
}]);
and the htmlIndex where i use the contoller:
<header>
<div class="container">
<div class="navbar">
<ul class="nav navbar-nav" ng-controller="NavController">
<li ng-class="navClass('home')"><a href='#/'>Home</a></li>
<li ng-class="navClass('home')"><a href='#/team1'>team1</a></li>
</ul>
</div>
</div>
</header>
i click the nav buttons nothing happens and in the console i get this error "Argument 'NavController' is not a function, got undefined"
Maybe you call controller in a wrong way. It should be called on a app like this:
angular.module('myApp')
.controller('NavController',
['$scope', '$location', function ($scope, $location) {
$scope.navClass = function (page) {
var currentRoute = $location.path().substring(1) || 'main';
return page === currentRoute ? 'active' : '';
};
}]);
Take a look at this fiddle for a complete code: https://jsfiddle.net/q91jozyr/
When you define the module with angular.module('myApp', ['ngRoute']) you need to save the reference in the variable myAppto reuse the module, when declaring the controller.
app.js:
var myApp = angular.module('myApp', ['ngRoute'])
Alternatively I suggest to call the controller by reusing the module like this:
controller:
angular.module('myApp').controller('NavController', [ /* etc... */ ]);
Note that the module is being reused, if you don't specifiy the dependencies again like angular.module('myApp') instead of angular.module('myApp', [ ]).
In both cases make sure the module myApp is bootstrapped by adding ng-app="myApp" to any of the parent elements, e.g. the <body>:
<body ng-app="myApp">