AngularJS $http put raw HTML element in the body - javascript

test.html
<html>
<body ng-app="myApp" ng-controller="myCtrl">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<p>Response from process.php is : {{message}}</p>
<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope, $http){
$http({
method : "post",
url : "process.php"
})
.then(function(response){
// First function handle success
$scope.message = response.data;
}, function(response){
// Second function handle error
$scope.message = response.status +' ('+ response.statusText + ' )';
})
});
</script>
</body>
</html>
process.php
<?php
$data = "<h1>Hey, how are you...???</h1>";
echo $data;
?>
Response from process.html is : <h1>Hey, how are you...???</h1>
You can see that the output is not as expected. It puts the h1 element in the body. But the output should be an heading.
How can I do this..?? Any suggestions please.
SOLVED
<div ng-bind-html="messageHtml"></div>
<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope, $http, $sce){
$http({
method : "post",
url : "process.php"
})
.then(function(response){
// First function handle success
$scope.message = response.data;
$scope.messageHtml = $sce.trustAsHtml($scope.message)
}, function(response){
// Second function handle error
$scope.messageHtml = response.status +' ('+ response.statusText + ' )';
})
});
</script>

Found solution
I have to use $sce with ng-bind-html .
HTML
<p ng-bind-html="messageHtml"></p>
Controller
$scope.message = response.data;
$scope.messageHtml = $sce.trustAsHtml($scope.message)

you can use ng-bind-html like this
<p ng-bind-html="message" ></p>

Check This code :
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope, $http,$sce){
$http({
method : "post",
url : "process.php"
})
.then(function(response){
// First function handle success
$scope.message = $sce.trustAsHtml(response.data);
}, function(response){
// Second function handle error
$scope.message = response.status +' ('+ response.statusText + ' )';
})
});
</script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<p>Response from process.php is : <span ng-bind-html="message"></span></p>
</body>
</html>

You have to use ng-bind-html directive.
Ref: https://docs.angularjs.org/api/ng/directive/ngBindHtml
<p>Response from process.php is : </p><div ng-bind-html="message"></div>

I have created a directive for just this scenario. You need to have angular-sanitize included in your project.
(function () {
'use strict';
angular
.module('yourModule')
.filter('to_trusted', ['$sce', function ($sce) {
return function (text) {
return $sce.trustAsHtml(text);
};
}]);
})();
Then in your HTML, you can write:
<p>{{message | to_trusted}}</p>

Related

Angular does not pick $scope.variable_name

Below is my HTML code.
<div class="container" ng-app="mintcart">
<div class="panel panel-default" ng-controller="categoriesctrl">
<input type="hidden" ng-model="session.sid" value="<?php echo session_id();?>"/>
<div class="panel-body">
<div class="row">
<ul class="nav nav-pills">
<?php
$i = 0;
while($i < count($list)){
$name = $list[$i]['categoryName'];
$id = $list[$i]['id'];
$normalUrl = $list[$i]['normalImageUrl'];
$hoverUrl = $list[$i]['hoverImageUrl'];
if($i == 0){
echo "<li role='presentation' class='active' ng-click='loadproducts($id)'><a href='#' >$name</a></li>";
} else {
echo "<li role='presentation' ng-click='loadproducts($id)'><a href='#''>$name</a></li>";
}
$i++;
}
?>
</ul>
</div>
</div>
</div>
</div>
ANd below is my JS code.
var app = angular.module('mintcart',[]);
app.controller('categoriesctrl', function($scope, $http){
var auth = {};
$http({
method: 'GET',
url: baseurl + 'api/get_product_categories'
}).then(function successCallback(response) {
$scope.categories = response.data.categories;
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
$scope.loadproducts = function(item_id) {
alert($scope.session.sid);
$http({
method: 'GET',
url: baseurl + 'api/get_items_in_category_cart/' + item_id
}).then(function successCallback(response) {
$scope.items = response.data.products;
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
//$scope.Language = lang;
};
});
When the loadproducts function is called the alert($scope.session.sid); gives me "undefined". I can't understand why my element is not being picked up.
Any help is greatly appreciated.
php works on the server side, you need to set the variable using a javascript not on the view.
Create a variable in JavaScript which gets the returned content of PHP.
var sessionid = <?php echo session_id();?>
then , you can access the variable in controller,
var app = angular.module("MyApp", []);
app.controller("categoriesctrl", function($scope) {
$scope.session.sid = sessionid ;
console.log($scope.session.sid);
});

AngularJS insert data twice to database

I am trying to insert data to database through angularJS but the data inserted twice.. I have tried to use ngRoute but still I face the same problem.
app.js
var app = angular.module("addDepApp", []);
app.controller('insertDepCtl', function($scope, $http) {
var isSend = false;
$scope.$on('newuser', function(event, data){
load(true);
});
var load = function(isEvent){
if($scope.$parent.newuser != null){
isSend = true;
}
};
load();
$scope.insertDepartment = function () {
console.log("called insertDepartment");
if (isSend == true){
$scope.newuserSend = {'org_id': $scope.$parent.newuser.org_id, 'dep_name': $scope.department};
$http.post("http://192.168.1.12:8888/XXXX/XXX/insertDep.php/",$scope.newuserSend)
}
}
});
add.html
<body ng-app="addDepApp">
<div class="12u$" ng-controller="insertDepCtl">
<input type="button" value="تسجيل" class="special" id="signup" ng-click="insertDepartment()"/>
</div>
</body>
Remove ng-controller="insertDepCtl" from your html code, your router injects this for you. Right now, you're calling everything twice
I have changed the code to this and now it works fine!!
$scope.insertDepartment = function () {
if (isSend == true) {
var request = $http({
method: "post",
url: "http://192.168.1.106:8888/XXXX/XXX/insertDep.php/",
data: {'org_id': $scope.$parent.newuser.org_id, 'dep_name': $scope.department},
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});
}
}

code not working as intended in angular

I have the following code set up:
var videoControllers = angular.module('videoControllers', []);
videoControllers.videoControllers('VideoDetailController', function($scope, $routeParams, $http){
$http.get('http://localhost:8000/videos/api/video/' + $routeParams.videoId + '/?format=json').success(
function(data){
$scope.video = data;
});
})
This code keeps giving me an error which state that: 'videoControllers.videoControllers is not a function'. The tutorial I am using is written in that manner and it is working, but my project gives me this error. Can anyone please help.
Becuase the keyword is controller while you are using videoControllers. Change your code as below:
var videoControllers = angular.module('videoControllers', []);
videoControllers.controller('VideoDetailController', function($scope, $routeParams, $http){
$http.get('http://localhost:8000/videos/api/video/' + $routeParams.videoId + '/?format=json')
.success(function(data){
$scope.video = data;
});
});
Try this coz in ur code ur not accessing controller
angular.module('videoControllers').controller('VideoDetailController', function($scope, $routeParams, $http){
$http.get('http://localhost:8000/videos/api/video/' + $routeParams.videoId + '/?format=json').success(
function(data){
$scope.video = data;
});
});

Angular function inside JavaScript function

I have defined an AngularJS dialog as follows in my angular-app.js:
angular.module('myAPP', ['ngMaterial']).controller('AppCtrl', function($scope, $mdDialog) {
$scope.status = ' ';
$scope.showAdvanced = function(ev,_url) {
$mdDialog.show({
controller: DialogController,
templateUrl: _url,
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose:true
}).then(function(answer) {
$scope.status = 'You said the information was "' + answer + '".';
}, function() {
$scope.status = 'You cancelled the dialog.';
});
};
});
function DialogController($scope, $mdDialog) {
$scope.hide = function() {
$mdDialog.hide();
};
$scope.cancel = function() {
$mdDialog.cancel();
};
$scope.answer = function(answer) {
$mdDialog.hide(answer);
};
}
And in my HTML page I have this:
<a ng-click="openDetailDialog()">Show details</a>
<script type="text/javascript">
function openDetailDialog(id) {
var id = getValue(id, 'id');
showAdvanced($event,'${readDetailURL}&id=' + id + '/');
}
</script>
The problem is that when I add the function showAdvanced() inside another function, it doesn't work.
When I call this function directly in ng-click, it works.
This works:
<a ng-click="showAdvanced($event,'http:myurl/test/id');">Show details</a>
Why?
First you can't attach or bind something that is not on the $scope, or the controller itself.
<a ng-click="openDetailDialog()">Show details</a>
That's wrong.
And second you can't access variables attached to the scope from plain javascript, 2WDB (two way data binding) just include HTML. And of course angular works with encapsulated scope.
The function ´showAdvanced()actually is part of the$scope`element. When you do this in your html:
<a ng-click="showAdvanced()">text</a>
AngularJs changes that (behind the scenes) to $scope.showAdvanced()
If you want to call it from javascript, you could try and change your function call to
`$scope.showAdvanced()`

Non-functioning view when sharing controller

I have a simple app that fetches images from Flickr and renders them. The application is divided into two views, SearchView and PhotoListView. Previously, when treating these as one view, everything worked fine, and photos were rendered. Now, when sharing controller, both are rendered but the list of photos is never populated. When debugging I can see that the photos are indeed fetched.
I'm terribly new at Angular, so I really don't have any good guesses at what the problem could be, but possibly that the two views don't share scope properly?
Here's the routing (using ui-router):
// app.js
'use strict';
angular.module('pruApp', ['ui.state'])
.config(function ($httpProvider, $stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/photos');
$stateProvider
.state('/', {
url: '/photos',
views: {
'SearchView': {
templateUrl: '/views/search.html',
controller: 'PhotoCtrl'
},
'PhotoListView': {
templateUrl: '/views/photo-list.html',
controller: 'PhotoCtrl'
}
}
});
// Remove X-Requested-With header to enable CORS
delete $httpProvider.defaults.headers.common['X-Requested-With'];
});
The controller and factory that talks to the Flickr service:
// photo.js
'use strict';
angular.module('pruApp')
.controller('PhotoCtrl', function ($scope, PhotoFactory) {
$scope.search = function() {
PhotoFactory.getPhotos($scope.searchQuery).then(function (data) {
$scope.photos = [];
var parsedData = angular.fromJson(data);
var items = parsedData.photos.photo;
for (var i = 0; i < items.length; ++i) {
var photo = items[i];
$scope.photos.push({
title: photo.title,
image: 'http://farm' + photo.farm + '.staticflickr.com/' + photo.server + '/' + photo.id + '_' + photo.secret + '_m.jpg',
link: 'http://www.flickr.com/photos/' + photo.owner + '/' + photo.id
});
}
});
};
});
angular.module('pruApp')
.factory('PhotoFactory', function ($http, $q) {
return {
_get: function(url) {
var deferred = $q.defer();
$http.get(url)
.success(function (data) {
deferred.resolve(data);
})
.error(function (data, status) {
deferred.reject('An error occured: ' + status);
});
return deferred.promise;
},
getPhotos: function (searchQuery) {
return this._get('http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=<MY_KEY>&tags=' + searchQuery + '&format=json&nojsoncallback=1');
}
};
});
This is where the views are injected:
<!-- index.html -->
<div class="main" role="main">
<div class="search" ui-view="SearchView"></div>
<div class="results" ui-view="PhotoListView"></div>
</div>
Search template:
<!-- search.html -->
<h2 class="struct">Search</h2>
<form>
<fieldset>
<div class="cell">
<input type="search" name="search-query" class="search-query" placeholder="Search photos by tags (e.g. lolcat, rageface, bronie)" ng-model="searchQuery" required>
</div>
<div class="cell">
<button type="submit" name="search-button" class="search-button" ng-click="search()">Search</button>
</div>
</fieldset>
</form>
Photo list template:
<!-- photo-list.html -->
<h2 class="struct">Search results</h2>
<ul>
<li ng-repeat="photo in photos">
<h3>{{ photo.title }}</h3>
<img ng-src="{{ photo.image }}" alt="{{ photo.title }}">
<p class="author">Author: <span>{{ photo.author }}</span></p>
</li>
</ul>
So your problem seems to be that you are calling the method to get the photos on one instance of the controller but that doesn't share data with your other controller. On first read I had missed your factory definition, still the problem is the variable in scope on the controller is in a different instance.
The way you can handle this is by always returning a promise from the factory/service to the controller, the in the controller using the promise to assign the scope. This way if the service has data already available it will automatically populate in your controllers scope, and if not as soon as it comes available it can be populated.
Really it looks like you're doing what I'm saying in the paragraph above but I don't see where the search function is called within the controller. Essentially you should just have something in the controller that is populating the $scope.photos array directly off the service. Then separately you should have your search function which fires off the call to the service passing along the parameter.
Another option is to $watch your properties in the factory/service and update a variable in the $scope of the controller on changes.
angular.module('pruApp')
.factory('PhotoFactory', function ($http, $q) {
return {
photos: [],
_get: function(url) {
var deferred = $q.defer();
$http.get(url)
.success(function (data) {
this.photos = [];
var parsedData = angular.fromJson(data);
var items = parsedData.photos.photo;
for (var i = 0; i < items.length; ++i) {
var photo = items[i];
this.photos.push({
title: photo.title,
image: 'http://farm' + photo.farm + '.staticflickr.com/' + photo.server + '/' + photo.id + '_' + photo.secret + '_m.jpg',
link: 'http://www.flickr.com/photos/' + photo.owner + '/' + photo.id
});
}
deferred.resolve(data);
})
.error(function (data, status) {
deferred.reject('An error occured: ' + status);
});
return deferred.promise;
},
getPhotos: function (searchQuery) {
return this._get('http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=<MY_KEY>&tags=' + searchQuery + '&format=json&nojsoncallback=1');
}
};
});
and in the controller
angular.module('pruApp')
.controller('PhotoCtrl', function ($scope, PhotoFactory) {
$scope.$watch(function () { return PhotoFactory.photos; }, function(data) {
$scope.photos = data;
}); // initialize the watch
$scope.search = function() {
PhotoFactory.getPhotos($scope.searchQuery);
};
}
});

Categories

Resources