Angular TypeError: name.replace is not a function for ng-style

Steven10172 picture Steven10172 · Jul 21, 2015 · Viewed 13.8k times · Source

I'm new to angular and keep getting the following error in the console TypeError: name.replace is not a function. I'm not sure what's exactly causing it, but it seems to be caused by the ng-style statement and maybe something to do with the camelCase?

The part I don't understand is why ng-style="isFrontView() || !matches && {'display': 'none'}" throws the error, but ng-style="!isFrontView() || !matches && {'display': 'none'}" doesn't throw the error.

In an attempt to remedy the situation I tried removing the camelCase from the function name and went all lowercase. I also attempted to use !!isFrontView(), but neither seemed to remove the error message.

Do anyone know what is the cause of this error message and a potential fix?

Error Message

HTML Template:

<div class="system-view">
    <div class="controller-container fill" id="systemView1" ng-style="isFrontView() || !matches && {'display': 'none'}">
        <canvas id="canvasLayer-shell" data-layername="front" width="617" height="427"></canvas>
        <i ng-if="!matches" class="fa fa-repeat toggle-view" ng-click="changeView()" ng-touch="changeView()"></i>
    </div>
    <div class="controller-container fill" id="systemView2" ng-style="!isFrontView() || !matches && {'display': 'none'}">
        <canvas id="canvasLayer-shell" data-layername="back" width="617" height="427"></canvas>
        <i ng-if="!matches" class="fa fa-undo toggle-view" ng-click="changeView()" ng-touch="changeView()"></i>
    </div>
</div>

Backend Code:

$scope.frontView = true;
$scope.matches = true;

$scope.isFrontView = function() {
   return $scope.frontView;
};

$scope.changeView = function() {
    $scope.frontView = !$scope.frontView;
};

P.S. Even with the console error everything still functions normally.

Answer

PSL picture PSL · Jul 21, 2015

Your potential issue is due to the incorrect usage of ng-style. ng-style sets a watcher on the expression and sets the element's style with the help of jquery/jqlite element.css. And Inside element.css css attribute (name) is converted to the standard camel casing (which uses regex string replace). In your specific case the expression evaluated to boolean (true) instead of an object (ng-style does this for each property) and boolean does not have replace property (which is available on a string object) and hence it fails. You can test this by converting your expression to evaluate to a string by using string concatenation.

i.e ng-style="'' + (isFrontView() || !matches && {'display': 'none'})"

Looking at the expression all you need it to hide and show the element, you could well make use of ng-show/ng-hide directives to achieve that.