opensas
opensas

Reputation: 63425

Use a custom function from an angular template

I'm displaying urls from an angular template, but I'd like to 'slugify' it, that is, replace those ugly chars. Right now I just want to replace spaces with '_'.

This is the code I have on my index.html file

<a ng-href="#/{{url}}">{{name}}</a>

I'd like to define a slugify function like this:

slugify = function(url) {
  return url.replace(' ', '_');
};

And then being able to call it from every the template like this

<a ng-href="#/{{slugify(url)}}">{{name}}</a>

How could I achieve it?

-- edit

I finally went with @underscore solution (added it to the $rootScope) and from a normal controller it works ok. But from a template inside the ng-app directive, but with no ng-controller, it works too, but it gives me the following error, lots of times:

Error: error:interr
Interpolation Error
Can't interpolate: #/{{slug(b.link)}}
TypeError: undefined is not a function

This is the offending code:

<a ng-show='b.link' ng-href="#/{{slug(b.link)}}">{{b.name}}</a>

I tried with regular href and ng-href, and also with $root.slug, but it always throws the same error a dozen times, nevertheless it works ok.

Also tried defining a filter, like Peter said, and it gave me the same error:

Can't interpolate: #/{{b.link | slug}}
TypeError: undefined is not a function

Nevertheless, it worked ok too...

--

ok, final edit

It seems when angular is bootstraping the input value might be undefined (as explained here: https://stackoverflow.com/a/18573426/47633)

I could solve the nasty error message with:

presuApp.filter('slug', function() {
  return function(input) {
    return input ? input.replace(/ /g, '_') : '';
  }
});

Upvotes: 0

Views: 300

Answers (3)

Peter Ashwell
Peter Ashwell

Reputation: 4302

Create a function in your controller e.g.

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
   $scope.theInput = 'example input';
   $scope.slugify = function(input) {
       input = input.replace(' ', '_');
       return input;
   }
});

Here's a plunkr:

http://plnkr.co/edit/RARhGQzQoGPtWhoFColL?p=preview

A more correct way might be to use a filter:

app.filter('slugify', function() {
  return function(input) {
    input = input.replace(' ', '_');
    return input
  }
})

And in the template you put:

using a filter:
{{ theInput | slugify }}

Also added that to plunkr

Upvotes: 2

floor
floor

Reputation: 1572

In your controller you can bind $scope to a function to make it accessible via the html.

$scope.slugify = function(url) {
  return url.replace(' ', '_');
};

Upvotes: 1

underscore
underscore

Reputation: 6887

"And then being able to call it from every the template like this"

In this case you should use $rootScope instead of controller scope.

just use it in the $rootScope

$rootScope.slugify = function(url) {
  return url.replace(' ', '_');
};

Define it in the app.run(); . So the function will define when angular bootstrap

Upvotes: 1

Related Questions