0

I want to display some html on a scene (an image of a man or a woman), depending on the gender of the person logged on my website. The directive ng-bind-html works when I define "imageToLoad" statically. However, it doesn't work if my html to bind is defined by a function.

The console tells me: TypeError: $scope.getHtml is not a function

Here is my simplified code:

HTML:

<div id="img-container" ng-controller="sceneCtrl" ng-bind-html="imgToLoad">
</div>

JS:

.controller('sceneCtrl', function($scope, $http, $sce){
    /* This works
    ** $scope.imgToLoad = $sce.trustAsHtml('<img id="over2" src="imgMale.png"/>');
    */

    $scope.imgToLoad=$scope.getHtml();

    $scope.getHtml=function(){

      var gender='male';
      if(gender=='male'){
        return $sce.trustAsHtml('<img id="over2" src="imgMale.png"/>');
      }
      else if(gender=='female'){
        return $sce.trustAsHtml('<img id="over2" src="imgFemale.png"/>');
      }
      return 'error getHtml';
    }
})

I simplified the JS with a variable saying the gender, but eventually the gender will be given by the backend, from a database.

According to my research, I may have to use "compile", but I have no idea how this works.

Thanks for your help !

2
  • Did you get any error? Commented Feb 22, 2017 at 9:50
  • Try putting function definition before the following line: $scope.imgToLoad=$scope.getHtml(); Commented Feb 22, 2017 at 9:55

4 Answers 4

3

The problem here is that you are calling $scope.getHtml before you initialised it so at the time you call the value is undefined.

Don't put functions into $scope unless you need them there, and don't call them through $scope from javascript when you can call them directly. This should work:

.controller('sceneCtrl', function($scope, $http, $sce){

    $scope.imgToLoad = getHtml();

    function getHtml(){

      var gender='male';
      if(gender=='male'){
        return $sce.trustAsHtml('<img id="over2" src="imgMale.png"/>');
      }
      else if(gender=='female'){
        return $sce.trustAsHtml('<img id="over2" src="imgFemale.png"/>');
      }
      return 'error getHtml';
    }
})
Sign up to request clarification or add additional context in comments.

2 Comments

This solution works perfectly, thank you very much. I'm new to AngularJS so I thought it was mandatory to declare the functions into $scope for it to work properly.
Note that someone tried to edit this answer to move the function to the top because that is their preferred style. That would have been better as a comment rather than an edit so I rejected it. Two problems: I try to make answers match the style of the question where there's no real reason to change, and I also prefer myself to put function after all the executable code in the controller body. Also see angular style guide github.com/johnpapa/angular-styleguide/blob/master/a1/…
0

Use custom directive ng-html

DEMO: http://jsfiddle.net/AntonWebDev2012/mb4nv5my/

.directive('ngHtml', [ '$compile', function ($compile) {
    return function (scope, elem, attrs) {
      if (attrs.ngHtml) {
        elem.html(scope.$eval(attrs.ngHtml));
        $compile(elem.contents())(scope);
      }
      scope.$watch(attrs.ngHtml, function (newValue, oldValue) {
        if (newValue && newValue !== oldValue) {
          elem.html(newValue);
          $compile(elem.contents())(scope);
        }
      });
    };
  } ]);

Comments

0

Direct html worked, So the problem is : function is called before it is initialized, try calling it after. Eg. $scope.getHtml=function(){ } $scope.imgToLoad=$scope.getHtml();

Comments

0

Here My Code.. I made some changes..

.controller('sceneCtrl',['$scope','$http','$sce', function($scope, $http, $sce) {

var gender='male';
$scope.getHtml=function(){
  if(gender=='male'){
    return $sce.trustAsHtml('<h3>Pablo</h3><img id="over2" src="http://www.freeiconspng.com/uploads/male-icon-19.png"/>');
  }
  else if(gender=='female'){
    return $sce.trustAsHtml('<h3>Picaso</h3><img id="over2" src="http://weknowyourdreams.com/images/female/female-01.jpg"/>');
  }
  return 'error getHtml';
}; 
 $scope.imgToLoad = $scope.getHtml();


 }]);

})(window.angular);

First I Declare the getHTML function and then call it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.