AngularJS Directive Passing String

JavascriptStringAngularjsAngularjs DirectiveParameter Passing

Javascript Problem Overview


This directive is trying to create an HTML element called progress bar that tracks progress as you move page to page. I'm trying to develop it to be used as : <progress-bar progress='1' max='6' error="true"></progress-bar>

I'm simply trying to pass the information from the ^^element in html to my directive and process the information to change the progress bar appropriately.

This is working for "progress" and "max" which take integer values, but for some reason the commented out code, which would process "error" (which is a string) is causing problems. I'm new to angularJS so I'm sorry if any of this sounds confusing or unclear... please ask if I need to elaborate/clarify. Thanks in advance!

app.directive('progressBar', function(){

var compileProgressBar = function(scope, elem, attrs) {
	var append = '<nav class="navbar navbar-fixed-bottom navbar-footer" role="navigation">\
  					<div class="container">\
  						<div class="row">';
	var i = 1;
	while (i <= parseInt(scope.max)) {
		if (i <= parseInt(scope.progress)) {
			//if (scope.error == "true"){
				//...
			//}
			//else {
			append += '<div class="col-xs-1"><div class="circle-filled"><center>'+i+'</center></div></div>'
			//}
		} else {
			append += '<div class="col-xs-1"><div class="circle-hallow"><center>'+i+'</center></div></div>'
		}
		i++;
	}
	append += '</div></div></nav>'
	elem.append(append);
	elem.bind('click', function(){
		if (scope.progress > 1) {
			history.back();
			scope.$apply();
		}
	});
}

return {
	restrict: 'AE',
	scope: {
		max: '=max',
		progress: '=progress'
		//error: '=error'
	},
	link: compileProgressBar
}

});

Javascript Solutions


Solution 1 - Javascript

In your directive, you're using the bi-directional binding of attributes from the global scope to the directive local scope.

In this mode, the attribute value in the html is evaluated as an expression and thus your directive tries to bind its local scope.error to the result of evaluating true as an expression.

When you test scope.error == "true", you're actually testing true == "true" and this evaluates to false in javascript.

To fix your problem, you can:

  • either use a quoted string when calling your directive:

    <progress-bar progress='1' max='6' error="'true'"></progress-bar>
    
  • or change your binding mode in your directive since you don't need the bi-directional binding. @ variables are always of type string.

    return {
        restrict: 'AE',
        scope: {
           max: '@max',
           progress: '@progress',
           error: '@error'
        },
        link: compileProgressBar
    }
    

You can find more information on the binding modes in Angular $compile documentation

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionprofoundWandererView Question on Stackoverflow
Solution 1 - JavascriptrlutaView Answer on Stackoverflow